Merge remote-tracking branch 'origin/fara' into roman

This commit is contained in:
3lswear
2022-02-19 22:31:32 +03:00
29 changed files with 690 additions and 265 deletions

View File

@@ -2,9 +2,9 @@ NAME = webserv
CXX = clang++
SANFLAGS = -fsanitize=address
# SANFLAGS = -fsanitize=address
# SANFLAGS = -fsanitize=leak
SANFLAGS = -fsanitize=leak
DEBUGFLAGS = -g -fno-limit-debug-info

View File

@@ -1,18 +1,18 @@
[[server]]
name = "pohek1.org"
host = "127.0.0.1"
port = 8080
body_size_limit = 10000000
host = "127.0.0.1" # check inet_addr()
port = 8080 # check num, (0, 65536)
body_size_limit = 10000000 #(pofig and > 0)
[server.error_page]
403 = "www/errorFolder/index2.html"
"404" = "www/errorFolder/error_404.html" # throw exception if not string
[[server.location]]
location = "/"
root = "www/"
location = "/" # mandatory
root = "www/" # check valid
methods = ["GET", "POST", "DELETE"]
autoindex = true
autoindex = true #check if bool
directory_file = "index.html"
upload_accept = true
upload_dir = "/var/www/html/upload"
upload_accept = true #throw exception if not bool
upload_dir = "www/upload" # check valid
[[server.location]]
location = "/images"
root = "www/images"
@@ -20,7 +20,7 @@
autoindex = true
[[server.location]]
location = "/images/168.png"
redirect = ["301", "http://127.0.0.1:8080/168.png"]
redirect = ["301", "http://127.0.0.1:8080/168.png"] #throw exception if no array, or more 2 elem, or elem is not str
[[server.location]]
location = "/errorFolder/images/168.png"
redirect = ["301", "http://127.0.0.1:8080/168.png"]
@@ -32,20 +32,16 @@
location = "*.png"
root = "www/images/pngImg"
methods = ["GET"]
[[server.location]]
location = "*.ico"
root = "www/images/icoImg"
methods = ["GET"]
[[server.location]]
location = "/errorFolder"
root = "www/errorFolder"
methods = ["GET", "POST"]
autoindex = false
autoindex = true
[[server.location]]
location = "*.php"
root = "www/script"
autoindex = false
cgi_pass = "/usr/bin/php-cgi"
cgi_pass = "/usr/bin/php-cgi" #check valid
[[server]]
name = "pohek2.org"
host = "127.0.0.1"
@@ -63,7 +59,7 @@
autoindex = true
directory_file = "index.html"
upload_accept = false
upload_dir = "/var/www/html/upload"
upload_dir = "www/upload"
[[server]]
name = "localhost"
host = "127.0.0.1"
@@ -81,4 +77,4 @@
autoindex = true
directory_file = "index.html"
upload_accept = false
upload_dir = "/var/www/html/upload"
upload_dir = "www/upload"

View File

@@ -2,28 +2,29 @@
name = "pohek1.org"
host = "127.0.0.1"
port = 8080
body_size_limit = 100000000
[[server.location]]
location = "/"
root = "www/tester/"
root = "tester/"
methods = ["GET"]
autoindex = true
directory_file = "index.html"
[[server.location]]
location = "/put_test"
root = "www/tester/"
root = "tester/"
methods = ["PUT"]
autoindex = true
upload_dir = "www/tester/upload_here/"
upload_dir = "tester/upload_here/"
[[server.location]]
location = "*.bla"
cgi_pass = "/usr/bin/php-cgi"
cgi_pass = "ubuntu_cgi_tester"
[[server.location]]
location = "/post_body"
root = "www/tester/"
root = "tester/"
methods = ["POST"]
body_size_limit = 100
[[server.location]]
location = "/directory"
methods = ["GET"]
root = "www/tester/YoupiBanane/"
root = "tester/YoupiBanane/"
directory_file = "youpi.bad_extension"

View File

@@ -30,6 +30,8 @@
#include <sys/time.h>
#include <arpa/inet.h>
#include <wait.h>
#include <exception>
#include <csignal>
#include <netinet/in.h>
#include <fcntl.h>

164
second/index.html Normal file
View File

@@ -0,0 +1,164 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8" />
<title>Название сайта</title>
</head>
<body>
<!--Создаём таблицу контейнер, которой задаём следующее
оформление:
border="1" - рамка вокруг контейнера. Увеличив число, можно увеличить толщину рамки.
align="center" - размещаем контейнер по центру экрана.
rules="rows" - убираем двойную рамку.
style="width:60%;" - добавляем стилевое свойства, делающее
контейнер и весь сайт "резиновым".
Сделать полноценный адаптивный дизайн, этим способом невозможно.-->
<table
border="1"
align="center"
rules="rows"
style="width:60%;">
<!--Создаём строку-->
<tr>
<!--Создаём ячейку строки-->
<td>
<!--ШАПКА САЙТА-->
<!--В ячейке строки создаём ещё одну таблицу для шапки сайта.
Оформление:
border="1" - двойная рамка толщиной в 1px
background="images/168.png" - картинка в шапке сайта, если требуется.
Адрес картинки вы должны вставить свой.
bgcolor="#7FFFD4" - фоновый цвет в шапке, если нет картинки.
cellpadding="10" - отступ содержимого от рамки не менее 10px.
style="width:100%; border-radius:5px;" - добавляем "резиновость"
и закругляем уголки рамки-->
<table
border="1"
background="images/168.png"
bgcolor="#7FFFD4"
cellpadding="10"
style="width:100%; border-radius:5px;">
<!--Создаём строку таблицы-->
<tr>
<!--Создаём столбец таблицы-->
<th>
<!--Содержание ячейки столбца-->
<h1>Название сайта (организации)</h1>
<h3>Описание сайта</h3>
<!--Закрываем таблицу-->
</th>
</tr>
</table>
<!--ОСНОВНОЙ КОНТЕНТ-->
<!--В этой же ячейке контейнера создаём ещё одну таблицу
для основного контента.
Оформление как и в предыдущей таблице-->
<table
border="1"
bgcolor="#e6e6fa"
cellpadding="10"
style="width:100%; border-radius:5px;">
<!--Создаём строку-->
<tr>
<!--Создаём ячейку
Оформление:
rowspan="2" - объединяем две ячейки в одну.
Число объединяемых ячеек по числу ячеек в сайдбаре.
style="width:80%" - основной контент занимает 80% всей площади,
оставшиеся 20% для сайдбара-->
<td
rowspan="2"
style="width:80%">
<h2>Страница</h2>
<!--Начинаем абзац с красной строки-->
<p style="text-indent:20px">
Здравствуйте уважаемые будущие веб-мастера!
Мне 55 лет и я рад приветствовать Вас на своём сайте.
Этот сайт первый, который я разработал самостоятельно,
а до этого умел только входить в интернет.</p>
<p style="text-indent:20px">Почему я решил его сделать?
За те 3 месяца, пока разбирался в
сайтостроении и создавал этот ресурс обнаружилось,
что авторы руководств по созданию
сайтов считают многие нюансы само собой разумеющимися
и не обращают на них внимание
А мне, учитывая возраст и «опыт», было не просто
понять как раз эти нюансы, они отнимали больше всего
времени.</p>
<!--Закрываем ячейку-->
</td>
<!--САЙДБАР-->
<!--Создаём ячейку сайдбара-->
<td bgcolor="#e6e6fa">
<h3>Меню</h3>
<!--Абзац для ссылки на страницу сайта-->
<p>
<!--Ссылка на страницу сайта-->
<a href="">
<!--Картинка маркера перед названием страницы-->
<img src="http://trueimages.ru/img/00/06/f4fffdb5.png">
<!--Название страницы
style="margin-left:5px;" - отступ названия от маркера-->
<span style="margin-left:5px;">Страница</span></a>
<!--Закрываем абзац-->
</p>
<p>
<a href="">
<img src="http://trueimages.ru/img/31/ab/4dcb087c2ae4305edcd15171696.jpg">
<span style="margin-left:5px;">Страница 1</span;></a>
</p>
<p>
<a href="">
<img src="http://trueimages.ru/img/31/ab/4dcb087c2ae4305edcd15171696.jpg">
<span style="margin-left:5px;">Страница 2</span></a>
</p>
<!--Закрываем строку Меню-->
</td>
</tr>
<!--Создаём строку с дополнительной информацией-->
<tr>
<!--Ячейка с дополнительной информацией-->
<td
bgcolor="#e6e6fa"
align="center">
<h3>Общая информация</h3>
<p>Текст общей информации или реклама</p>
<!--Закрываем ячейку с общей информацией
и таблицу основного контента-->
</td>
</tr>
</table>
<!--ПОДВАЛ-->
<!--Создаём таблицу подвала-->
<table
border="1"
bgcolor="#7FFFD4"
height="100"
cellpadding="10"
style="width:100%; border-radius:5px;">
<!--Создаём строку.-->
<tr>
<!--Создаём столбец-->
<th>
<h3>Подвал</h3>
<!--Закрываем таблицу подвала. При желании в подвале можно
сделать несколько строк и столбцов-->
</th>
</tr>
</table>
<!--Закрываем таблицу контейнера-->
</td>
</tr>
</table>
</body>
</html>

View File

@@ -82,7 +82,7 @@ std::string CgiHandle::executeCgi()
int byte_read = 1;
std::string body;
argv[0] = const_cast<char *>(_response.getCgiPass().data());
argv[0] = const_cast<char *>(_response._fullURI.data());
argv[1] = NULL;
try
{
@@ -92,7 +92,6 @@ std::string CgiHandle::executeCgi()
{
std::cerr << RED << e.what() << RESET << '\n';
}
printenv(env);
sI = dup(STDIN_FILENO);
sO = dup(STDOUT_FILENO);
@@ -100,9 +99,9 @@ std::string CgiHandle::executeCgi()
FILE *fOt = tmpfile();
long fdin = fileno(fIn);
long fdOut = fileno(fOt);
DBOUT << BLUE << "in CGI exe" << ENDL;
// DBOUT << "BODY[\n" << _request.getBody() << "\n]" << ENDL;
write(fdin, _request.getBody().data(), _request.getBody().size());
if (_request.getBody() != NULL)
write(fdin, _request.getBody()->data(), _request.getBody()->size());
lseek(fdin, 0, SEEK_SET);
pid = fork();
if (pid == -1)
@@ -124,9 +123,10 @@ std::string CgiHandle::executeCgi()
waitpid(-1, NULL, 0);
lseek(fdOut, 0, SEEK_SET);
byte_read = 1;
while (byte_read)
{
bzero(buffer, BUFFSIZE);
memset(buffer, 0, BUFFSIZE + 1);
byte_read = read(fdOut, buffer, BUFFSIZE);
body.append(buffer, byte_read);
}
@@ -147,21 +147,21 @@ void CgiHandle::initEnvVariables()
{
std::map<std::string, std::string>::iterator it;
std::map<std::string, std::string> tmp1 = _request.getClientFields();
_scriptName = _response.getFullURI().substr(_response.getFullURI().rfind("/"));
_scriptName = _response._fullURI.substr(_response._fullURI.rfind("/"));
it = tmp1.find("content_type");
if (it != tmp1.end())
_variable["AUTH TYPE"] = it->second;
else
_variable["AUTH TYPE"] = "";
_variable["CONTENT_LENGTH"] = toString(_request.getContentLength());
_variable["CONTENT_LENGTH"] = (_request.getBody() == NULL) ? "0" : toString(_request.getBody()->size());
it = _request.getClientFields().find("content-type");
_variable["CONTENT_TYPE"] = "";
_variable["GATEWAY_INTERFACE"] = std::string("CGI/1.1");
_variable["SCRIPT_NAME"] = _response.getFullURI();
_variable["SCRIPT_FILENAME"] = _response.getFullURI();
_variable["SCRIPT_NAME"] = _response._fullURI;
_variable["SCRIPT_FILENAME"] = _response._fullURI;
_variable["PATH_TRANSLATED"] = _response.getFullURI();
_variable["PATH_TRANSLATED"] = _request.getURI();
_variable["REQUEST_URI"] = _request.getURI();
_variable["PATH_INFO"] = _request.getURI();
@@ -184,7 +184,7 @@ void CgiHandle::initEnvVariables()
tmp = getEnvFormat(it->first);
_variable["HTTP_" + tmp] = it->second;
}
printSSmap(_variable);
// printSSmap(_variable);
}
CgiHandle::~CgiHandle()

View File

@@ -111,7 +111,7 @@ bool Client::isChunked(void)
// Возвращает истина, если отправлены все данные клиента.
bool Client::allSended(void)
{
if (_toSend.size() <= _sended)
if (response_len <= _sended)
done = true;
return (done);
}
@@ -135,59 +135,64 @@ void Client::increaseRecvCounter(unsigned int n)
}
//Генерирует response. Далее респонс можно получить через функцию getStrToSend()
int Client::sendResponse(int fd)
{
_response.setData(_request, _config);
_response.generate();
_headerToSend = _response.getHeader();
_bodyToSend = _response.getBody();
_ret = sendData(fd, _headerToSend + _bodyToSend);
// int Client::sendResponse(int fd)
// {
// _response.setData(_request, _config);
// _response.generate();
// _headerToSend = _response.getHeader();
// _bodyToSend = _response.getBody();
// _ret = sendData(fd, _headerToSend + _bodyToSend);
return (_ret);
}
// return (_ret);
// }
std::string Client::generateRespons(void)
{
size_t len;
// std::string Client::generateRespons(void)
// {
// size_t len;
_response.setData(_request, _config);
_response.generate();
_headerToSend = _response.getHeader();
_bodyToSend = _response.getBody();
_toSend = _headerToSend + _bodyToSend;
// _response.setData(_request, _config);
// _response.generate();
// _headerToSend = _response.getHeader();
// _bodyToSend = _response.getBody();
// *_toSend = _headerToSend + _bodyToSend;
len = _toSend.size();
response_len = len;
_to_send_char = new char[len + 1];
std::memcpy(_to_send_char, _toSend.c_str(), len + 1);
// len = _toSend->size();
// response_len = len;
// _to_send_char = new char[len + 1];
// std::memcpy(_to_send_char, _toSend->c_str(), len + 1);
// DBOUT << "len = " << len << ENDL;
// DBOUT << "strlen = " << strlen(_to_send_char) << ENDL;
// DBOUT << "content_lenth = " << _request.getContentLength() << ENDL;
return (_toSend);
}
// return (*_toSend);
// }
std::string Client::generateRespons(std::vector<ServerConfig *> &configs)
{
size_t len;
location *tmp;
std::vector<location *> tmp;
_config = Config::getConfig(configs, _request, connected_to);
tmp = Config::getLocation(_config->getLocations(), _request.getURI());
_response.setData(_request, _config, tmp);
_response.generate2(connected_to);
_headerToSend = _response.getHeader();
_bodyToSend = _response.getBody();
_toSend = _headerToSend + _bodyToSend;
_toSend = new std::string;
*_toSend = (_response.getBody() == NULL) ? _response.getHeader() : _response.getHeader() + *_response.getBody();
len = _toSend.size();
len = _toSend->size();
response_len = len;
_to_send_char = new char[len + 1];
std::memcpy(_to_send_char, _toSend.c_str(), len + 1);
std::memcpy(_to_send_char, _toSend->c_str(), len + 1);
return (_toSend);
std::cout << PINK << "\n[["<< YELLOW << "Request header\n{" << ENDL;
std::cout << BLUE << _request.getHeader() << YELLOW << "},\n" << ENDL;
std::cout << GREEN << "Response Header\n{" << ENDL;
std::cout << BLUE << _response.getHeader() << GREEN << "}" << PINK << "]]\n"<< ENDL;
delete _toSend;
if (_request.getBody() != NULL)
_request.freeData();
_response.freeData();
return (_headerToSend);
}
//-------------------------------------------------Error---------------------------------------
@@ -261,7 +266,6 @@ void Client::clear(void)
_config = NULL;
_bodyToSend = "";
_headerToSend = "";
_toSend = "";
if (_to_send_char)
delete[] _to_send_char;
}

View File

@@ -26,7 +26,7 @@ private:
std::string _stringBUF;
std::string _bodyToSend;
std::string _headerToSend;
std::string _toSend;
std::string *_toSend;
char *_to_send_char;
std::map<std::string, std::string> _errorCode;

View File

@@ -36,6 +36,21 @@ int isDir(std::string path)
return (-1);
return (-1);
}
void copyLocation(location *dest, location *src)
{
dest->autoindex = src->autoindex;
dest->cgi_pass = src->cgi_pass;
dest->clientBodySize = src->clientBodySize;
dest->directoryFile = src->directoryFile;
dest->location = src->location;
dest->methods = src->methods;
dest->redirect = src->redirect;
dest->root = src->root;
dest->uploadAccept = src->uploadAccept;
dest->uploadDir = src->uploadDir;
}
int Config::calcLen(std::string &s1, std::string &s2)
{
unsigned long len = 0;
@@ -48,7 +63,7 @@ int Config::calcLen(std::string &s1, std::string &s2)
return (len);
}
location *Config::getLocation(std::vector<location *> &arr, std::string &URI)
std::vector<location *> Config::getLocation(std::vector<location *> &arr, std::string &URI)
{
unsigned int tryLen = URI.size();
std::string tryLocation;
@@ -57,6 +72,7 @@ location *Config::getLocation(std::vector<location *> &arr, std::string &URI)
std::string suffix1;
std::vector<location *>::iterator it;
std::vector<location *> step_1;
std::vector<location *> step_2;
suffix = URI.substr(URI.rfind(".") + 1, URI.size() - URI.rfind("."));
while (tryLen)
@@ -79,7 +95,7 @@ location *Config::getLocation(std::vector<location *> &arr, std::string &URI)
it = step_1.begin();
tmp = *it;
if (tmp->location == URI || tmp->location.size() > 1)
return (tmp);
step_2.push_back(tmp);
}
it = arr.begin();
@@ -90,20 +106,22 @@ location *Config::getLocation(std::vector<location *> &arr, std::string &URI)
{
suffix1 = tmp->location.substr(2);
if (suffix1 == suffix)
return (tmp);
step_2.push_back(tmp);
}
it++;
}
if (step_2.empty())
{
it = arr.begin();
while (it != arr.end())
{
tmp = *it;
if (tmp->location == "/")
return (tmp);
step_2.push_back(tmp);
it++;
}
return (NULL);
}
return (step_2);
}
ServerConfig *Config::getConfig(std::vector<ServerConfig *> &arr, Request &request, serverListen &data)

View File

@@ -16,7 +16,7 @@ public:
~Config();
static int calcLen(std::string &, std::string &);
static location *getLocation(std::vector<location *> &, std::string &URI);
static std::vector<location *> getLocation(std::vector<location *> &, std::string &URI);
static ServerConfig *getConfig(std::vector<ServerConfig *> &, Request &request, serverListen &data);
private:

View File

@@ -13,7 +13,7 @@ Request::Request()
_received = 0;
_headerSize = 0;
_lifeTime = 5;
_body = NULL;
}
Request::Request(char *str)
@@ -28,15 +28,22 @@ Request::Request(char *str)
_contentLength = 0;
_headerSize = 0;
_lifeTime = 5;
_body = NULL;
}
//-------------------------------------------------Get/Set---------------------------------------
void Request::freeData(void)
{
delete _body;
}
std::string &Request::getURI(void)
{
return (_URI);
}
std::string &Request::getBody(void)
std::string *Request::getBody(void)
{
return (_body);
}
@@ -89,7 +96,7 @@ bool Request::getChunked(void)
return (_chunked);
}
unsigned int Request::getContentLength(void) const
ssize_t Request::getContentLength(void) const
{
return (_contentLength);
}
@@ -97,10 +104,14 @@ unsigned int Request::getHeaderSize(void) const
{
return (_headerSize);
}
unsigned int Request::getRecved(void) const
ssize_t Request::getRecved(void) const
{
return (_received);
}
std::string &Request::getHeader(void)
{
return _head;
}
void Request::setData(char *str)
{
this->_data = str;
@@ -127,6 +138,25 @@ void Request::increaseRecvCounter(unsigned int n)
{
_received += n;
}
std::string urlDecode(std::string &url) {
std::string ret;
char ch;
size_t i, ii;
for (i=0; i < url.length(); i++) {
if (size_t(url[i])==37) {
sscanf(url.substr(i+1,2).c_str(), "%lx", &ii);
ch=static_cast<char>(ii);
ret+=ch;
i=i+2;
} else {
ret+=url[i];
}
}
return (ret);
}
void Request::parseURI(std::string str)
{
std::string tmp;
@@ -141,6 +171,10 @@ void Request::parseURI(std::string str)
}
else
_URI = str;
std::string sIn = _URI;
_URI = urlDecode(sIn);
_fullURI = HOME + _URI;
}
@@ -196,24 +230,25 @@ void Request::splitData(std::string &data)
str = _head.substr(_headerSize);
_head = tmp;
_head_ok = true;
parseHeader();
if ((_contentLength == 0 && !_chunked) || (_method == "GET"
|| _method == "DELETE" || _method == "HEAD"))
_body_ok = true;
else
_body = new std::string;
}
}
if (badCode(_ret))
return ;
else if (_chunked)
else if (_chunked && !_body_ok)
{
_body.insert(_body.end(), str.begin(), str.end());
if (checkEnd(_body, "0\r\n\r\n") == 0)
_body->insert(_body->end(), str.begin(), str.end());
if (checkEnd(*_body, "0\r\n\r\n") == 0)
_body_ok = true;
}
else if (_head_ok && !_body_ok)
{
_body.insert(_body.end(), str.begin(), str.end());
_body->insert(_body->end(), str.begin(), str.end());
if ((_received - _headerSize) == _contentLength)
{
_body_ok = true;
@@ -221,7 +256,7 @@ void Request::splitData(std::string &data)
}
if (_head_ok && _body_ok && _chunked)
{
std::string &tmp = _body;
std::string &tmp = *_body;
std::string subchunk = tmp.substr(0, 100);
std::string newBody = "";
int chunksize = strtol(subchunk.c_str(), NULL, 16);
@@ -235,7 +270,7 @@ void Request::splitData(std::string &data)
subchunk = tmp.substr(i, 100);
chunksize = strtol(subchunk.c_str(), NULL, 16);
}
_body = newBody;
*_body = newBody;
}
}
@@ -380,7 +415,6 @@ void Request::clear(void)
_ret = 200;
_row = 0;
_URI = "";
_body = "";
_host = "";
_query = "";
_method = "";

View File

@@ -14,13 +14,13 @@ private:
int _ret;
int _row;
int _lifeTime;
unsigned int _contentLength;
unsigned int _received;
ssize_t _contentLength;
ssize_t _received;
unsigned int _headerSize;
std::string _URI;
std::string _head;
std::string _body;
std::string *_body;
std::string _host;
std::string _query;
std::string _method;
@@ -37,7 +37,7 @@ private:
bool _chunked;
public:
std::string &getURI(void);
std::string &getBody(void);
std::string *getBody(void);
std::string &getHost(void);
std::string &getQuery(void);
std::string &getMethod(void);
@@ -48,9 +48,9 @@ public:
ServerConfig *getConfig(void);
int getCode(void);
int getLifeTime(void);
unsigned int getContentLength(void) const;
ssize_t getContentLength(void) const;
unsigned int getHeaderSize(void) const;
unsigned int getRecved(void)const;
ssize_t getRecved(void)const;
char *getPointerBody(void)const;
std::map<std::string, std::string> getClientFields(void);
@@ -81,6 +81,8 @@ public:
void copyFromMap(void);
void clear(void);
void splitData(std::string &);
void freeData(void);
std::string &getHeader(void);
void increaseRecvCounter(unsigned int n);
~Request();

View File

@@ -6,16 +6,25 @@ Response::Response()
{
initErrorCode();
_Autoindex = true;
_body = NULL;
_header = NULL;
_code = 200;
}
//-------------------------------------------------GET/SET---------------------------------------
void Response::freeData(void)
{
if (_body != NULL)
delete _body;
delete _header;
}
std::string Response::getHeader(void)
{
return (_header);
return (*_header);
}
std::string Response::getBody(void)
std::string *Response::getBody(void)
{
return (_body);
}
@@ -27,12 +36,21 @@ void Response::setData(Request request, ServerConfig *config)
_config = config;
}
void Response::setData(Request &request, ServerConfig *config, location *loc)
void Response::setData(Request &request, ServerConfig *config, std::vector<location *> &loc)
{
_request = request;
_code = request.getCode();
_config = config;
_location = loc;
if (loc.empty())
_code = 404;
else
{
_location = loc[0];
if (loc.size() == 2)
_cgi_Pass = loc[1]->cgi_pass;
else
_cgi_Pass = _location->cgi_pass;
}
}
void Response::setHeaderBlocks(void)
@@ -59,7 +77,10 @@ void Response::setContentType(void)
void Response::setContentLength()
{
_contentLength = _body.size();
if (_body != NULL)
_contentLength = _body->size();
else
_contentLength = 0;
}
void Response::setServer(void)
@@ -100,21 +121,25 @@ serverListen Response::getListen()
std::string Response::getCgiPass(void)
{
return (_location->cgi_pass);
return (_cgi_Pass);
}
ssize_t Response::getMaxBodySize(void)
{
return (_maxBodySize);
}
//-------------------------------------------------File---------------------------------------
void Response::OpenResponseFile(const char *path)
{
DBOUT << "in OPEN RESPONSE FILE " << path << ENDL;
std::stringstream ss;
std::ifstream file(path, std::ifstream::in);
if (file.is_open())
{
ss << file.rdbuf();
_body = ss.str();
*_body = ss.str();
file.close();
}
else
@@ -138,14 +163,14 @@ void Response::OpenErrorFile(int code)
if (file.is_open())
{
ss << file.rdbuf();
_body = ss.str();
*_body = ss.str();
file.close();
}
else
_body = getErrorPage(code);
*_body = getErrorPage(code);
}
else
_body = getErrorPage(code);
*_body = getErrorPage(code);
}
std::string Response::getContentType(void)
@@ -205,15 +230,16 @@ std::string Response::getFullURI(void)
int pos = 0;
pos = _request.getURI().rfind("/");
tmp = _request.getURI().substr(pos);
if (!_location->uploadDir.empty())
_upload_dir = _location->uploadDir + tmp;
tmp = _location->root + tmp;
}
else
{
DBOUT << "location" << _location->location << ENDL;
tmp = _request.getURI().substr(len);
DBOUT << "tmp1 " << RED << tmp << ENDL;
if (!_location->uploadDir.empty())
_upload_dir = _location->uploadDir + tmp;
tmp = _location->root + tmp;
DBOUT << "tmp2" << RED << tmp << ENDL;
}
if (_request.isDir(tmp) == 0)
{
@@ -226,7 +252,11 @@ std::string Response::getFullURI(void)
}
else
ret = tmp;
if (_upload_dir.empty())
_upload_dir = ret;
DBOUT << PINK << "location " << _location->location << ENDL;
DBOUT << PINK << "fullURI " << ret << ENDL;
DBOUT << PINK << "upload dir " << _upload_dir << ENDL;
return (ret);
}
@@ -236,8 +266,8 @@ void Response::generateBody(void)
{
if (_Autoindex)
{
_body = Autoindex::getPage(_request.getURI(), _fullURI, _request.getHost(), _listen.port);
if (_body.empty())
*_body = Autoindex::getPage(_request.getURI(), _fullURI, _request.getHost(), _listen.port);
if (_body->empty())
_code = 404;
}
else
@@ -263,16 +293,17 @@ bool Response::allowedMethod(std::string &method)
{
if (*it == method)
return (true);
DBOUT << BLUE << *it << ENDL;
it++;
}
if (_location->cgi_pass.empty())
if (!_cgi_Pass.empty() && (method == "GET" || method == "POST"))
return (true);
_code = 405;
return (false);
}
void Response::generateHeader(void)
{
_header = new std::string;
std::stringstream ss;
std::string tmp;
@@ -281,15 +312,15 @@ void Response::generateHeader(void)
ss << "Content-Type: " << _contentType << "\r\n";
ss << "Content-Length: " << _contentLength << "\r\n";
ss << "Server: " << _server << "\r\n";
if (!_keepAlive.empty())
ss << "Keep-Alive: " <<_keepAlive << "\r\n";
// if (!_keepAlive.empty())
// ss << "Keep-Alive: " <<_keepAlive << "\r\n";
ss << "Date: " << _date << "\r\n";
if (!_cacheControl.empty())
ss << "Cache-Control: " << _cacheControl << "\r\n";
if (!_locationSTR.empty())
ss << "Location: " << _locationSTR << "\r\n";
ss << "\r\n";
_header = ss.str();
*_header = ss.str();
}
void Response::generate()
@@ -311,7 +342,7 @@ void Response::generate2(serverListen &l)
{
_code = 404;
}
else
else if (!_request.badCode(_code))
{
_listen = l;
_errorPages = _config->getErrorPages();
@@ -322,18 +353,10 @@ void Response::generate2(serverListen &l)
_fullURI = getFullURI();
_method = _request.getMethod();
_maxBodySize = (_location->clientBodySize > 0) ? _location->clientBodySize : _config->getClientBodySize();
if (_maxBodySize > 0)
_code = (_request.getRecved() > _maxBodySize) ? 413 : _code;
DBOUT << BLUE << "max size" << _maxBodySize << ENDL;
DBOUT << BLUE << "_location size" << _location->clientBodySize << ENDL;
DBOUT << BLUE << "_config sieze" << _config->getClientBodySize() << ENDL;
DBOUT << BLUE << "req size " << _request.getContentLength() << ENDL;
DBOUT << BLUE << "recv size " << _request.getRecved() << ENDL;
if (_maxBodySize > 0 && _request.getBody() != NULL)
_code = (_request.getBody()->size() > (unsigned long)_maxBodySize) ? 413 : _code;
}
DBOUT << "fullURI " << _fullURI << ENDL;
DBOUT << RED << "code is " << _code << ENDL;
if (_request.badCode(_code) || (!allowedMethod(_method) && _location->cgi_pass.empty()) || isRedirect())
if (_request.badCode(_code) || !allowedMethod(_method) || isRedirect())
{
invalidClient();
return;
@@ -364,6 +387,7 @@ bool Response::isRedirect()
void Response::invalidClient(void)
{
_body = new std::string;
if (!isRedirect())
OpenErrorFile(_code);
setHeaderBlocks();
@@ -375,58 +399,56 @@ void Response::invalidClient(void)
void Response::methodGet(void)
{
if (!_location->cgi_pass.empty())
_body = new std::string;
if (!_cgi_Pass.empty())
{
CgiHandle cgi(_request, *this);
_body = cgi.executeCgi();
unsigned long pos = _body.find("\r\n\r\n");
*_body = cgi.executeCgi();
unsigned long pos = _body->find("\r\n\r\n");
if (pos != std::string::npos)
{
std::string tmp = _body.substr(0, pos);
std::string tmp = _body->substr(0, pos);
unsigned long stat = tmp.find("Status: ");
unsigned long type = tmp.find("Content-type: ");
if (stat != std::string::npos)
_code = atoi(tmp.substr(stat + 8, 3).c_str());
if (type != std::string::npos)
_contentType = tmp.substr(type + 14, tmp.find("\r\n", type+14));
_body.erase(_body.begin(), _body.begin() + pos + 4);
_body->erase(_body->begin(), _body->begin() + pos + 4);
}
}
else
generateBody();
setHeaderBlocks();
generateHeader();
std::cout << GREEN << "GET method called\n" << ZERO_C;
DBOUT << GREEN << "GET method called\n" << ZERO_C;
}
void Response::methodPost(void)
{
if (!_location->cgi_pass.empty())
if (!_cgi_Pass.empty())
{
_body = new std::string;
CgiHandle cgi(_request, *this);
_body = cgi.executeCgi();
unsigned long pos = _body.find("\r\n\r\n");
*_body = cgi.executeCgi();
DBOUT << "CGI SIZE BODY " << _body->size() << ENDL;
unsigned long pos = _body->find("\r\n\r\n");
if (pos != std::string::npos)
{
std::string tmp = _body.substr(0, pos);
std::string tmp = _body->substr(0, pos);
unsigned long stat = tmp.find("Status: ");
unsigned long type = tmp.find("Content-type: ");
if (stat != std::string::npos)
_code = atoi(tmp.substr(stat + 8, 3).c_str());
if (type != std::string::npos)
_contentType = tmp.substr(type + 14, tmp.find("\r\n", type+14));
_body.erase(_body.begin(), _body.begin() + pos + 4);
_body->erase(_body->begin(), _body->begin() + pos + 4);
}
}
else
{
std::ofstream outfile(_fullURI.c_str(), std::ios::out | std::ios::binary);
outfile.write(_request.getBody().data(), _request.getBody().size());
outfile.close();
_code = 204;
}
setHeaderBlocks();
generateHeader();
DBOUT << GREEN << "POST method called" << ENDL;
@@ -435,16 +457,16 @@ void Response::methodPost(void)
void Response::methodPut(void)
{
_code = 201;
if (_request.isFile(_fullURI) == 0)
if (_request.isFile(_upload_dir) == 0)
_code = 204;
std::ofstream file(_fullURI.c_str(), std::ios::out | std::ios::binary);
std::ofstream file(_upload_dir.c_str(), std::ios::out | std::ios::binary);
if (!file.is_open())
_code = 403;
else
{
file.write(_request.getBody().data(), _request.getBody().size());
}
file.write(_request.getBody()->data(), _request.getBody()->size());
file.close();
}
setHeaderBlocks();
generateHeader();
DBOUT << GREEN << "PUT method called" << ENDL;
@@ -554,4 +576,5 @@ std::string Response::getErrorPage(int code)
Response::~Response()
{
}

View File

@@ -10,8 +10,8 @@ class Response
{
private:
serverListen _listen;
std::string _body;
std::string _header;
std::string *_body;
std::string *_header;
Request _request;
ServerConfig *_config;
location *_location;
@@ -20,13 +20,12 @@ private:
std::map<int, std::string> _errorPages;
bool _Autoindex;
serverListen _hostPort;
std::string _fullURI;
std::string _method;
private:
std::string _contentType;
unsigned int _contentLength;
unsigned int _maxBodySize;
ssize_t _contentLength;
ssize_t _maxBodySize;
std::string _server;
std::string _keepAlive;
std::string _date;
@@ -34,6 +33,8 @@ private:
std::string _locationSTR;
std::string _contentLanguage;
std::string _transferEncoding;
std::string _upload_dir;
std::string _cgi_Pass;
void setHeaderBlocks(void);
void setContentType(void);
@@ -62,22 +63,24 @@ public:
serverListen getListen(void);
std::string getCgiPass(void);
std::string getHeader(void);
std::string getBody(void);
std::string *getBody(void);
static std::string getReasonPhrase(std::string);
static std::string getReasonPhrase(int);
std::string getErrorPage(int code);
std::string getFullURI();
ssize_t getMaxBodySize(void);
bool isRedirect(void);
bool allowedMethod(std::string &);
void setData(Request, ServerConfig *);
void setData(Request &, ServerConfig *, location *location);
void setData(Request &, ServerConfig *, std::vector<location *> &);
public:
std::string _fullURI;
void OpenResponseFile(const char *path);
void OpenErrorFile(int code);
void initErrorCode(void);
void generate();
void generate2(serverListen &);
void freeData(void);
Response();
~Response();

View File

@@ -3,7 +3,6 @@
#include <cassert>
#include <cstdio>
#include <map>
// #include "parse.hpp"
#define THREAD_NUM 100
#define MAX_EVENTS
@@ -40,22 +39,21 @@ void Server::readConfig(char *filename)
// TOMLMap *root = NULL;
// root = parse(filename);
config::TOMLParser parser(filename);
try
{
parser.parse();
_root = parser.root;
DBOUT << RED << "PARSED !!!" << ENDL;
}
catch (std::domain_error &e)
{
std::cerr << RED << "FATAL: ";
std::cerr << e.what() << RESET << std::endl;
// root->clear();
config::clean_parsed(parser.root);
// delete parser.root;
// exit(-1);
return;
}
// catch (std::domain_error &e)
// {
// std::cerr << RED << "FATAL: ";
// std::cerr << e.what() << RESET << std::endl;
// // root->clear();
// // config::clean_parsed(parser.root);
// // delete parser.root;
// // exit(-1);
// return;
//
// }
// catch (config::Tokenizer::InvalidToken &e)
// {
// std::cerr << RED << "FATAL: ";
@@ -81,11 +79,9 @@ void Server::readConfig(char *filename)
++it;
}
config::clean_parsed(parser.root);
DBOUT << RED << "GONNA CLEAN_PARSED" << ENDL;
}
void Server::sendData(Client &client, int fd)
{
/* std::string tmp = client.getStrToSend(); */
@@ -141,6 +137,7 @@ void Server::readSocket(Client &client, int fd)
// client.setRawData(buf);
client.increaseRecvCounter(bytes_read);
status = client.parseRequest();
(void)status;
// client_map[fd].printClientInfo();
if (client.allRecved())
@@ -197,6 +194,12 @@ void Server::add_to_epoll_list(int fd, unsigned int ep_events)
<< ENDL;
}
void sigHandler(int sig)
{
if (sig == SIGINT)
throw ConfigException("SIGINT called. Server shutdown!");
}
void Server::start(void)
{
/* Socket server_sock(AF_INET, SOCK_STREAM, 0, _port, "127.0.0.1"); */
@@ -208,6 +211,7 @@ void Server::start(void)
unsigned int client_events = EPOLLIN;
unsigned int server_events = EPOLLIN;
std::signal(SIGINT, sigHandler);
_epoll_fd = epoll_create(1337);
@@ -254,7 +258,7 @@ void Server::start(void)
{
ready_num = epoll_wait(_epoll_fd, _events, MAX_CLIENT, 5000);
DBOUT << TURQ << "ready_num " << ready_num << ENDL;
// DBOUT << TURQ << "ready_num " << ready_num << ENDL;
if (ready_num < 0)
throw std::logic_error("epoll_ret");
@@ -323,6 +327,23 @@ void Server::start(void)
void Server::end(void)
{
}
//----------------------------------------------Other------------------------------------------------------------------------------------------------
void Server::checkError(int fd, std::string str)
{
if (fd < 0)
{
DBOUT << RED << "Server ERROR: " << str << ENDL;
exit(1);
}
else
DBOUT << GREEN << "Server SUCCESS: " << str << ENDL;
}
Server::~Server()
{
std::vector<ServerConfig *>::iterator pri;
std::vector<location *>::iterator loc;
@@ -342,23 +363,8 @@ void Server::end(void)
delete *pri;
pri++;
}
}
//----------------------------------------------Other------------------------------------------------------------------------------------------------
void Server::checkError(int fd, std::string str)
{
if (fd < 0)
{
DBOUT << RED << "Server ERROR: " << str << ENDL;
exit(1);
}
else
DBOUT << GREEN << "Server SUCCESS: " << str << ENDL;
}
Server::~Server()
{
config::clean_parsed(_root);
}

View File

@@ -15,6 +15,8 @@ class Server
private:
int _port;
int _epoll_fd;
TOMLMap *_root;
struct epoll_event _events[MAX_CLIENT];
struct sockaddr_in _addres;
std::string _ip;

View File

@@ -33,7 +33,7 @@ int &ServerConfig::getPort(void)
return (_port);
}
int &ServerConfig::getClientBodySize(void)
ssize_t &ServerConfig::getClientBodySize(void)
{
return (_clientBodySize);
}
@@ -90,18 +90,42 @@ void ServerConfig::setRoot(TOMLMap * data)
//--------------------------------------------------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)
{
if (node->get_type() != toml_node::NUM)
return (1);
throw ConfigException(getWrongTypeErrorMSG("body_size_limit", toml_node::NUM, node->get_type()));
_clientBodySize = node->getNum();
if (_clientBodySize < 0)
throw ConfigException("Invalid body_size_limit specified!");
return (0);
}
int ServerConfig::putErrorPage(toml_node *node)
{
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::iterator it;
std::string s;
@@ -110,7 +134,7 @@ int ServerConfig::putErrorPage(toml_node *node)
while (it != map->end())
{
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;
_errorPages[atoi(s.c_str())] = *it->second->getString();
++it;
@@ -120,22 +144,27 @@ int ServerConfig::putErrorPage(toml_node *node)
int ServerConfig::putHost(toml_node *node)
{
if (node->get_type() != toml_node::STRING)
return (1);
throw ConfigException(getWrongTypeErrorMSG("host", toml_node::STRING, node->get_type()));
_host = *node->getString();
int ret = inet_addr(_host.c_str());
if (ret == -1)
throw ConfigException("Invalid host specified!");
return (0);
}
int ServerConfig::putName(toml_node *node)
{
if (node->get_type() != toml_node::STRING)
return (1);
throw ConfigException(getWrongTypeErrorMSG("server_name", toml_node::STRING, node->get_type()));
_serverName = *node->getString();
return (0);
}
int ServerConfig::putPort(toml_node *node)
{
if (node->get_type() != toml_node::NUM)
return (1);
throw ConfigException(getWrongTypeErrorMSG("server_name", toml_node::NUM, node->get_type()));
_port = node->getNum();
if (_port < 0 || _port > 65536)
throw ConfigException("Invalid port specified!");
return (0);
}
@@ -170,62 +199,61 @@ int ServerConfig::putLocation(toml_node *node)
if (it1->first == "location")
{
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();
}
else if (it1->first == "root")
{
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();
}
else if (it1->first == "autoindex")
{
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();
}
else if (it1->first == "upload_accept")
{
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();
}
else if (it1->first == "upload_dir")
{
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();
}
else if (it1->first == "cgi_pass")
{
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();
}
else if (it1->first == "body_size_limit")
{
DBOUT << "BodySize in locaton" << ENDL;
if (node->get_type() != toml_node::NUM)
continue;
if (it1->second->get_type() != toml_node::NUM)
throw ConfigException(getWrongTypeErrorMSG("body_size_limit", toml_node::NUM, it1->second->get_type()));
tmp->clientBodySize = it1->second->getNum();
}
else if (it1->first == "directory_file")
{
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();
}
else if (it1->first == "methods")
{
if (it1->second->get_type() != toml_node::ARRAY)
continue ;
throw ConfigException(getWrongTypeErrorMSG("methods", toml_node::ARRAY, it1->second->get_type()));
Array = *it1->second->getArray();
it2 = Array.begin();
while (it2 != Array.end())
{
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()));
++it2;
}
@@ -233,15 +261,21 @@ int ServerConfig::putLocation(toml_node *node)
else if (it1->first == "redirect")
{
if (it1->second->get_type() != toml_node::ARRAY)
continue ;
throw ConfigException(getWrongTypeErrorMSG("redirect", toml_node::ARRAY, it1->second->get_type()));
Array = *it1->second->getArray();
if (Array.size() != 2)
throw ConfigException("The redirect field specified the wrong number of arguments!");
it2 = Array.begin();
if ((*it2)->get_type() != toml_node::STRING)
throw ConfigException(getWrongTypeErrorMSG("redirect elem", toml_node::STRING, (*it2)->get_type()));
str = *(*it2)->getString();
++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()));
}
else
std::cout << RED << it1->first << ZERO_C << std::endl;
std::cerr << RED << "Warning: unknown parameter: "<< it1->first << ZERO_C << std::endl;
}
_locations.push_back(tmp);
it++;
@@ -279,6 +313,86 @@ void ServerConfig::fillFields(void)
ret = identify(block);
++block;
}
checkConfig();
}
int ServerConfig::isFile(std::string path)
{
struct stat s;
if (stat(path.c_str(), &s) == 0)
{
if (s.st_mode & S_IFDIR)
return (-1);
else if (s.st_mode & S_IFREG)
return (0);
}
else
return (-1);
return (-1);
}
int ServerConfig::isDir(std::string path)
{
struct stat s;
if (stat(path.c_str(), &s) == 0)
{
if (s.st_mode & S_IFDIR)
return (0);
else if (s.st_mode & S_IFREG)
return (-1);
}
else
return (-1);
return (-1);
}
bool ServerConfig::checkFileAndDir(location *loc)
{
std::string root = loc->root;
std::string upload_dir = loc->uploadDir;
std::string directory_file = loc->directoryFile;
if (!root.empty())
{
if (isDir(root) != 0)
throw ConfigException("Directory " + root + " not found!");
}
if (!upload_dir.empty())
{
if (isDir(upload_dir) != 0)
throw ConfigException("Directory " + upload_dir + " not found!");
}
if (!directory_file.empty())
{
directory_file = root + "/" + directory_file;
if (isFile(directory_file) != 0)
throw ConfigException("File " + directory_file + " not found!");
}
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;
if (it == _locations.end())
throw ConfigException("Required routing settings are missing!");
while (it != _locations.end())
{
tmp = *it;
if (tmp->location.empty())
throw ConfigException("Location field not set!");
checkFileAndDir(tmp);
it++;
}
}
void ServerConfig::printFields(void)
@@ -290,43 +404,43 @@ void ServerConfig::printFields(void)
it1 = _errorPages.begin();
it = _locations.begin();
std::cout << RED << "-------------------------Server-Start----------------------------------\n" << ZERO_C;
std::cout << GREEN << "name" << " " << BLUE << _serverName << std::endl;
std::cout << GREEN << "host" << " " << BLUE << _host << std::endl;
std::cout << GREEN << "port" << " " << BLUE << _port << std::endl;
std::cout << GREEN << "client_body_size" << " " << BLUE << _clientBodySize << std::endl;
std::cout << GREEN << "location" << std::endl;
DBOUT << RED << "-------------------------Server-Start----------------------------------\n" << ZERO_C;
DBOUT << GREEN << "name" << " " << BLUE << _serverName << std::endl;
DBOUT << GREEN << "host" << " " << BLUE << _host << std::endl;
DBOUT << GREEN << "port" << " " << BLUE << _port << std::endl;
DBOUT << GREEN << "client_body_size" << " " << BLUE << _clientBodySize << std::endl;
DBOUT << GREEN << "location" << std::endl;
while (it != _locations.end())
{
std::cout << PINK << "------------------------------------------------\n";
std::cout << YELLOW << "location " << BLUE << (*it)->location <<std::endl;
std::cout << YELLOW << "root " << BLUE << (*it)->root <<std::endl;
std::cout << YELLOW << "directoryFile " << BLUE << (*it)->directoryFile <<std::endl;
std::cout << YELLOW << "uploadDir " << BLUE << (*it)->uploadDir <<std::endl;
std::cout << YELLOW << "autoindex " << BLUE << (*it)->autoindex <<std::endl;
std::cout << YELLOW << "uploadAccept " << BLUE << (*it)->uploadAccept <<std::endl;
std::cout << YELLOW << "cgi_pass " << BLUE << (*it)->cgi_pass <<std::endl;
std::cout << YELLOW << "client_body_size " << BLUE << (*it)->clientBodySize <<std::endl;
std::cout << YELLOW << "methods " << std::endl;
DBOUT << PINK << "------------------------------------------------\n";
DBOUT << YELLOW << "location " << BLUE << (*it)->location <<std::endl;
DBOUT << YELLOW << "root " << BLUE << (*it)->root <<std::endl;
DBOUT << YELLOW << "directoryFile " << BLUE << (*it)->directoryFile <<std::endl;
DBOUT << YELLOW << "uploadDir " << BLUE << (*it)->uploadDir <<std::endl;
DBOUT << YELLOW << "autoindex " << BLUE << (*it)->autoindex <<std::endl;
DBOUT << YELLOW << "uploadAccept " << BLUE << (*it)->uploadAccept <<std::endl;
DBOUT << YELLOW << "cgi_pass " << BLUE << (*it)->cgi_pass <<std::endl;
DBOUT << YELLOW << "client_body_size " << BLUE << (*it)->clientBodySize <<std::endl;
DBOUT << YELLOW << "methods " << std::endl;
it2 = (*it)->methods.begin();
while (it2 != (*it)->methods.end())
{
std::cout << BLUE << *it2 << " ";
DBOUT << BLUE << *it2 << " ";
it2++;
}
std::cout << std::endl;
DBOUT << std::endl;
it3 = (*it)->redirect.begin();
std::cout << YELLOW << "redirection" << RED << " " << it3->first << " " << BLUE << it3->second << std::endl;
DBOUT << YELLOW << "redirection" << RED << " " << it3->first << " " << BLUE << it3->second << std::endl;
++it;
std::cout << PINK << "------------------------------------------------\n";
DBOUT << PINK << "------------------------------------------------\n";
}
std::cout << GREEN << "error pages" << std::endl;
DBOUT << GREEN << "error pages" << std::endl;
while (it1 != _errorPages.end())
{
std::cout << YELLOW << it1->first << " " << BLUE << it1->second << std::endl;
DBOUT << YELLOW << it1->first << " " << BLUE << it1->second << std::endl;
++it1;
}
std::cout << RED << "-------------------------Server-End------------------------------------\n" << ZERO_C;
DBOUT << RED << "-------------------------Server-End------------------------------------\n" << ZERO_C;
}
ServerConfig::~ServerConfig()

View File

@@ -2,6 +2,7 @@
#define SERVERCONFIG_HPP
#include "webserv.hpp"
#include "ConfigException.hpp"
#include "parse.hpp"
struct location
@@ -15,7 +16,7 @@ struct location
std::vector<std::string> methods;
std::map<int, std::string> redirect;
std::string cgi_pass;
unsigned int clientBodySize;
ssize_t clientBodySize;
};
struct serverListen
@@ -33,7 +34,7 @@ private:
std::string _serverName;
std::string _host;
int _port;
int _clientBodySize;
ssize_t _clientBodySize;
std::map<int, std::string> _errorPages;
std::vector<location *> _locations;
@@ -47,11 +48,12 @@ public:
void setErrorPages(std::map<int, std::string>);
void setLocations(std::vector<location *>);
void setRoot(TOMLMap *);
void checkConfig(void);
std::string &getServerName(void);
std::string &getHost(void);
int &getPort(void);
int &getClientBodySize(void);
ssize_t &getClientBodySize(void);
std::vector<location *> &getLocations(void);
std::map<int, std::string> &getErrorPages(void);
TOMLMap *getRoot(void);
@@ -67,11 +69,18 @@ private:
int putName(toml_node *);
int putPort(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 *);
int isFile(std::string path);
int isDir(std::string path);
public:
void fillFields(void);
void printFields(void);
~ServerConfig();
};

View 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

View File

@@ -9,12 +9,25 @@ int main(int argc, char **argv)
(void)argv;
Server server;
char *path = (char *)"config/real.toml";
try
{
if (argv[1] != NULL)
server.readConfig(argv[1]);
server.setupConfig();
else
server.readConfig(path);
server.start();
server.end();
return (0);
}
catch(const ConfigException& e)
{
std::cerr << RED << "\n" << e.getMessage() << '\n' << ENDL;
}
catch (std::domain_error &e)
{
std::cerr << RED << "FATAL: ";
std::cerr << e.what() << RESET << std::endl;
}
}

View File

0
tester/index.html Normal file
View File

BIN
ubuntu_cgi_tester Executable file

Binary file not shown.

17
www/script/index2.php Normal file
View File

@@ -0,0 +1,17 @@
<?php
header('Content-type: image/png', true);
$entityBody = file_get_contents('php://input');
echo($entityBody);
// phpinfo();
// echo ("Content-type:text/html\r\n\r\n");
// echo ("<html>\n");
// echo ("<head>\n");
// echo ("<title>Hello World - First CGI Program</title>\n");
// echo ("</head>\n");
// echo ("<body>\n");
// echo ("<h2>Hello World! This is my first CGI program</h2>\n");
// echo ("</body>\n");
// echo ("</html>\n");
?>