diff --git a/config/simple.toml b/config/simple.toml index 31d9ecb..fba62df 100644 --- a/config/simple.toml +++ b/config/simple.toml @@ -8,17 +8,18 @@ [[server.location]] location = "/" root = "/var/www/html/jopa.html" + redirect = ["301", "http://localhost/secret"] methods = ["GET", "POST"] - directory_list = true - directory_fallback = "its_a_directory.html" + autoindex = true + directory_file = "its_a_directory.html" upload_accept = true upload_dir = "/var/www/html/upload" [[server.location]] location = "/secret/" root = "/var/www/html/secret.html" methods = ["GET"] - directory_list = false - directory_fallback = "oops.html" + autoindex = false + directory_file = "oops.html" [[server]] name = "2222" host = "10.0.0.1" @@ -33,7 +34,7 @@ location = "/root2/" root = "/var/www/html/jopa.html" methods = ["GET", "POST"] - directory_list = true - directory_fallback = "its_a_directory.html" + autoindex = true + directory_file = "its_a_directory.html" upload_accept = false upload_dir = "/var/www/html/upload" diff --git a/includes/webserv.hpp b/includes/webserv.hpp index 0bd8cab..6bc34d1 100644 --- a/includes/webserv.hpp +++ b/includes/webserv.hpp @@ -15,6 +15,8 @@ #define HOME "www" #define BUFFSIZE 1024 #define MAX_CLIENT 1000 +#define WHITESPACE " \n\r\t\f\v" + #include diff --git a/src/Autoindex/Autoindex.cpp b/src/Autoindex/Autoindex.cpp index 8cf6a96..715ee9e 100644 --- a/src/Autoindex/Autoindex.cpp +++ b/src/Autoindex/Autoindex.cpp @@ -4,11 +4,11 @@ Autoindex::Autoindex() { } -std::string Autoindex::getPage(std::string path, std::string host) +std::string Autoindex::getPage(std::string path, std::string allpath, std::string host) { - std::string allpath = HOME + path; DIR *dir = opendir(allpath.c_str()); struct dirent *dirEnt; + std::string tmp; std::string page =\ "\n\ \n\ @@ -24,11 +24,11 @@ std::string Autoindex::getPage(std::string path, std::string host) << allpath << "\" directory." << ZERO_C << std::endl; return ""; } - // if (allpath[0] != '/') - // path = "/" + path; for (dirEnt = readdir(dir); dirEnt; dirEnt = readdir(dir)) { - page = page + getReference(dirEnt->d_name, path, host); + tmp = dirEnt->d_name; + if (tmp != ".." && tmp != ".") + page = page + getReference(tmp, path, host); } page += "

\n\n\n"; closedir(dir); diff --git a/src/Autoindex/Autoindex.hpp b/src/Autoindex/Autoindex.hpp index 9ed6b9b..cc16b34 100644 --- a/src/Autoindex/Autoindex.hpp +++ b/src/Autoindex/Autoindex.hpp @@ -9,7 +9,7 @@ private: public: Autoindex(); - static std::string getPage(std::string path, std::string host); + static std::string getPage(std::string path, std::string allpath, std::string host); static std::string getReference(std::string file, std::string dir, std::string host); ~Autoindex(); }; diff --git a/src/Header/Header.cpp b/src/Header/Header.cpp index f099eef..942b7e4 100644 --- a/src/Header/Header.cpp +++ b/src/Header/Header.cpp @@ -1,55 +1,37 @@ #include "Header.hpp" -#define WHITESPACE " \n\r\t\f\v" +//-------------------------------------------------Constructors--------------------------------------- Header::Header() { - this->_row = 0; this->_fd = -1; - this->_autoIndex = 1; - initErrorCode(); - } Header::Header(char *str) { - this->_row = 0; this->_fd = -1; this->_buff = str; - this->_autoIndex = 1; - initErrorCode(); - parseRequest(); +} + +Header::Header(char *str, ServerConfig *config) +{ + this->_fd = -1; + this->_config = config; + this->_buff = str; + } //-------------------------------------------------GET/SET--------------------------------------- - -std::string Header::getErrorPage(int code) -{ - std::stringstream ss; - std::string Page; - - ss << "" << code <<" "<< getReasonPhrase(code) <<"" - <<"

" << code <<" " << getReasonPhrase(code) <<"

" - << "
poheck/1.0.0 (KDE)
"; - Page = ss.str(); - return (Page); -} - -std::map Header::getHeaderField(void) -{ - return (this->_headerField); -} - -HeaderHandl Header::getRequest(void) +Request Header::getRequest(void) { return (_request); } -HeaderHandl Header::getResponse(void) +Respons Header::getRespons(void) { - return (_response); + return (_respons); } int Header::getFd(void) @@ -69,274 +51,59 @@ void Header::setFd(int fd) //-------------------------------------------------Parsing--------------------------------------- -void Header::parseURI(std::string str) -{ - std::string tmp; - int pos; - - tmp = str; - pos = str.find("?"); - if (pos > 0) - { - _request._URI = tmp.substr(0, pos); - _request._query = tmp.erase(0, pos + 1); - } - else - _request._URI = str; - _request._fullURI = HOME + _request._URI; -} - -int Header::parseStartLine(std::string str) -{ - std::string tmp[3]; - - tmp[0] = str.substr(0, str.find(" ")); - str = str.erase(0 , str.find(" ") + 1); - tmp[1] = str.substr(0, str.find(" ")); - str = str.erase(0 , str.find(" ") + 1); - tmp[2] = str; - tmp[2].erase(tmp[2].find_last_not_of(" \n\r\t") + 1); - _request._method = tmp[0]; - parseURI(tmp[1]); - _request._version = tmp[2]; - - if (_request._version != "HTTP/1.1") - _ret = 505; - else if (_request._method != "GET" && _request._method != "POST" - && _request._method != "DELETE") - _ret = 405; - else if (isFile(_request._fullURI) != 0) - { - if (isDir(_request._fullURI) == 0 && _autoIndex) - _ret = 200; - else if (_autoIndex) - _ret = 404; - else - _ret = 403; - } - return (_ret); -} - -int Header::parseHeaderfield(std::string str) -{ - int distance; - std::string key; - std::string value; - - distance = str.find(":"); - if (distance < 0 && str != "\r") - return 400; - key = str.substr(0, distance); - std::transform(key.begin(), key.end(), key.begin(), ::tolower); - value = str.erase(0, distance + 1); - if (_headerField.find(key) != _headerField.end()) - { - std::cout << RED << "ERROR: double header-field" << ZERO_C << std::endl; - } - else - { - value = value.erase(0, value.find_first_not_of(WHITESPACE)); - value = value.substr(0, value.find_last_not_of(WHITESPACE) + 1); - _headerField[key] = value; - } - return 200; -} - int Header::parseRequest(void) { - std::string line; - std::stringstream buffStream; - - buffStream << _buff; - _ret = 200; - while (std::getline(buffStream, line, '\n') && _ret == 200) - { - if (_row == 0) - _ret = parseStartLine(line); - else - _ret = parseHeaderfield(line); - _row++; - } - if (_ret == 200) - _request.copyData(_headerField); + _request.setData(_buff); + _ret = _request.parseRequest(); + return (_ret); } //-------------------------------------------------FILE--------------------------------------- -int Header::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 Header::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); -} - -void Header::OpenResponseFile(const char *path) -{ - std::stringstream ss; - char buf[BUFFSIZE + 1] = {0}; - std::ifstream file(path); - - if (file.is_open()) - { - while (!file.eof()) - { - file.read(buf, BUFFSIZE); - ss << buf; - memset(buf, 0, BUFFSIZE + 1); - } - _fileToSend = ss.str(); - file.close(); - } - else - _fileToSend = getErrorPage(403); -} //-------------------------------------------------SEND--------------------------------------- -int Header::sendHeader(int fd) +int Header::sendData(int fd, std::string data) { - std::stringstream ss; - std::string tmp; - const char *header; - - ss << _request._version << " " << _ret << " " << getReasonPhrase(_ret) << "\r\nContent-Type: text/html\r\n\r\n"; - tmp = ss.str(); - header = tmp.c_str(); - std::cout << TURGUOISE << "Send Header\n" << YELLOW << tmp << ZERO_C; - send(fd, header, tmp.length(), 0); - return (0); + return (send(fd, data.c_str(), data.length(), 0)); } -int Header::sendResponse(int fd) +int Header::sendRespons(int fd) { - std::string path; + _respons.setData(_request, _config); + _respons.generate(); + _headerToSend = _respons.getHeader(); + _bodyToSend = _respons.getBody(); + _ret = sendData(fd, _headerToSend); + _ret = sendData(fd, _bodyToSend); - path = _request._fullURI; - sendHeader(fd); - if (_ret == 200 && isDir(path) == 0) - _fileToSend = Autoindex::getPage(_request._URI, _request._host); - else if (_ret == 200) - OpenResponseFile(path.c_str()); - else - _fileToSend = getErrorPage(_ret); - send(fd, _fileToSend.c_str(), _fileToSend.length(), 0); - - return (0); + return (_ret); } //-------------------------------------------------Error--------------------------------------- -std::map Header::_errorCode; - -void Header::initErrorCode(void) -{ - _errorCode["100"] = "Continue"; - _errorCode["101"] = "Switching Protocols"; - _errorCode["200"] = "OK"; - _errorCode["201"] = "Created"; - _errorCode["202"] = "Accepted"; - _errorCode["203"] = "Non-Authoritative Information"; - _errorCode["204"] = "No Content"; - _errorCode["205"] = "Reset Content"; - _errorCode["206"] = "Partial Content"; - _errorCode["300"] = "Multiple Choices"; - _errorCode["301"] = "Moved Permanently"; - _errorCode["302"] = "Found"; - _errorCode["303"] = "See Other"; - _errorCode["304"] = "Not Modified"; - _errorCode["305"] = "Use Proxy"; - _errorCode["306"] = "(Unused)"; - _errorCode["307"] = "Temporary Redirect"; - _errorCode["400"] = "Bad Request"; - _errorCode["401"] = "Unauthorized"; - _errorCode["402"] = "Payment Required"; - _errorCode["403"] = "Forbidden"; - _errorCode["404"] = "Not Found"; - _errorCode["405"] = "Method Not Allowed"; - _errorCode["406"] = "Not Acceptable"; - _errorCode["407"] = "Proxy Authentication Required"; - _errorCode["408"] = "Request Timeout"; - _errorCode["409"] = "Conflict"; - _errorCode["410"] = "Gone"; - _errorCode["411"] = "Length Required"; - _errorCode["412"] = "Precondition Failed"; - _errorCode["413"] = "Request Entity Too Large"; - _errorCode["414"] = "Request-URI Too Long"; - _errorCode["415"] = "Unsupported Media Type"; - _errorCode["416"] = "Requested Range Not Satisfiable"; - _errorCode["417"] = "Expectation Failed"; - _errorCode["500"] = "Internal Server Error"; - _errorCode["501"] = "Not Implemented"; - _errorCode["502"] = "Bad Gateway"; - _errorCode["503"] = "Service Unavailable"; - _errorCode["504"] = "Gateway Timeout"; - _errorCode["505"] = "HTTP Version Not Supported"; -} - -std::string Header::getReasonPhrase(std::string code) -{ - std::map::iterator it; - - it = _errorCode.find(code); - return (it->second); -} - -std::string Header::getReasonPhrase(int code) -{ - std::stringstream ss; - std::string nbr; - std::map::iterator it; - - ss << code; - nbr = ss.str(); - it = _errorCode.find(nbr); - return (it->second); -} - //-------------------------------------------------Other--------------------------------------- -void Header::printInfo(void) +void Header::printHeaderInfo(void) { + std::map map; std::map::iterator it; + std::map::iterator it1; - std::cout << PINK << "request method = " << _request._method << ZERO_C << std::endl; - std::cout << PINK << "request URI = " << _request._URI << ZERO_C << std::endl; - std::cout << PINK << "host = " << _request._host << ZERO_C << std::endl; - std::cout << PINK << "request query = " << _request._query << ZERO_C << std::endl; - std::cout << PINK << "request http versioin = " << _request._version << ZERO_C << std::endl; - std::cout << PINK << "request rows = " << _row << ZERO_C << std::endl; + map = _request.getHeaderFields(); + std::cout << PINK << "request method = " << _request.getMethod() << ZERO_C << std::endl; + std::cout << PINK << "request URI = " << _request.getURI() << ZERO_C << std::endl; + std::cout << PINK << "host = " << _request.getHost() << ZERO_C << std::endl; + std::cout << PINK << "request query = " << _request.getQuery() << ZERO_C << std::endl; + std::cout << PINK << "request http versioin = " << _request.getVersion() << ZERO_C << std::endl; std::cout << YELLOW << "request header:\n" << _buff << ZERO_C << std::endl; std::cout << TURGUOISE << "HEADER MAP" << ZERO_C << std::endl; - for ( it = _headerField.begin(); it != _headerField.end(); it++) + for ( it = map.begin(); it != map.end() ; it++) { std::cout << PINK << it->first << BLUE << it->second << ZERO_C << std::endl; + // std::cout << "1\n"; } } @@ -344,12 +111,11 @@ void Header::printInfo(void) void Header::clear(void) { _fd = -1; - _request._method = ""; - _row = 0; _buff = NULL; - _request._URI = ""; - _request._URI = ""; - _headerField.clear(); + _ret = 200; + _request.clear(); + _buff = NULL; + _config = NULL; } Header::~Header() diff --git a/src/Header/Header.hpp b/src/Header/Header.hpp index bfaf6b1..1d083e5 100644 --- a/src/Header/Header.hpp +++ b/src/Header/Header.hpp @@ -2,56 +2,50 @@ # define HEADER_HPP #include "webserv.hpp" -#include "HeaderHandl.hpp" #include "Autoindex.hpp" +#include "ServerConfig.hpp" +#include "Request.hpp" +#include "Respons.hpp" class Header { private: - HeaderHandl _request; - HeaderHandl _response; + Request _request; + Respons _respons; + ServerConfig *_config; private: - int _row; int _ret; - int _autoIndex; int _fd; char *_buff; - std::string _fileToSend; - std::map _headerField; + std::string _bodyToSend; + std::string _headerToSend; + std::map _errorCode; public: - static std::map _errorCode; - - std::map getHeaderField(void); - HeaderHandl getRequest(void); - HeaderHandl getResponse(void); - static std::string getReasonPhrase(std::string); - static std::string getReasonPhrase(int); - std::string getErrorPage(int code); + Request getRequest(void); + Respons getRespons(void); void setRawData(char *); void setFd(int); int getFd(void); - static void initErrorCode(void); - int isFile(std::string); - int isDir(std::string); - void OpenResponseFile(const char *path); - - int parseStartLine(std::string); - void parseURI(std::string); - int parseHeaderfield(std::string); - void printInfo(void); +public: int parseRequest(void); + + void printHeaderInfo(void); - int sendResponse(int fd); - int sendHeader(int fd); + int sendRespons(int fd); + int sendData(int , std::string data); void clear(void); + Header(); Header(char *); + Header(char *, ServerConfig *config); ~Header(); + + }; #endif diff --git a/src/Header/HeaderHandl.cpp b/src/Header/HeaderHandl.cpp deleted file mode 100644 index 71f65fc..0000000 --- a/src/Header/HeaderHandl.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "HeaderHandl.hpp" - - -HeaderHandl::HeaderHandl() -{ - -} - -HeaderHandl::~HeaderHandl() -{ - -} - -void HeaderHandl::copyData(std::map map) -{ - _host = map.find("host")->second; -} diff --git a/src/Header/HeaderHandl.hpp b/src/Header/HeaderHandl.hpp deleted file mode 100644 index 828b545..0000000 --- a/src/Header/HeaderHandl.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef HEADERHANDL_HPP -#define HEADERHANDL_HPP - -#include -#include - -class HeaderHandl -{ -public: - std::string _method; - std::string _URI; - std::string _fullURI; - std::string _version; - std::string _query; -public: - // std::string _allow; - // std::string _contentLenght; - std::string _contentType; - std::string _host; - // std::string _contentLanguage; - std::string _contentLocation; - // std::string _date; - // std::string _lastModified; - // std::string _transferEncoding; - // std::string _server; - // std::string _location; -public: - HeaderHandl(); - - void copyData(std::map); - - ~HeaderHandl(); -}; - - - -#endif \ No newline at end of file diff --git a/src/Header/Request.cpp b/src/Header/Request.cpp new file mode 100644 index 0000000..83eaabe --- /dev/null +++ b/src/Header/Request.cpp @@ -0,0 +1,232 @@ +#include "Request.hpp" + +//-------------------------------------------------Constructors--------------------------------------- + +Request::Request() +{ + _row = 0; + _ret = 200; +} + +Request::Request(char *str) +{ + _row = 0; + _ret = 200; + _data = str; +} + +//-------------------------------------------------Get/Set--------------------------------------- + +std::string Request::getURI(void) +{ + return (_URI); +} +std::string Request::getBody(void) +{ + return (_body); +} +std::string Request::getHost(void) +{ + return (_host); +} +std::string Request::getQuery(void) +{ + return(_query); +} +std::string Request::getMethod(void) +{ + return (_method); +} +std::string Request::getFullUri(void) +{ + return (_fullURI); +} +std::string Request::getVersion(void) +{ + return (_version); +} +std::string Request::getLocation(void) +{ + return (_location); +} +ServerConfig *Request::getConfig(void) +{ + return (_config); +} +int Request::getCode(void) +{ + return (_ret); +} +std::map Request::getHeaderFields(void) +{ + return (_headerField); +} + +void Request::setData(char *str) +{ + this->_data = str; +} +void Request::setData(char *str, ServerConfig *config) +{ + _data = str; + _config = config; +} +void Request::setConfig(ServerConfig *config) +{ + this->_config = config; +} + +//-------------------------------------------------Parsing--------------------------------------- + + +void Request::parseURI(std::string str) +{ + std::string tmp; + int pos; + + tmp = str; + pos = str.find("?"); + if (pos > 0) + { + _URI = tmp.substr(0, pos); + _query = tmp.erase(0, pos + 1); + } + else + _URI = str; + _fullURI = HOME + _URI; +} + +int Request::parseStartLine(std::string str) +{ + std::string tmp; + + _method = str.substr(0, str.find(" ")); + str = str.erase(0 , str.find(" ") + 1); + tmp = str.substr(0, str.find(" ")); + str = str.erase(0 , str.find(" ") + 1); + _version = str; + _version.erase(_version.find_last_not_of(WHITESPACE) + 1); + parseURI(tmp); + + if (_version != "HTTP/1.1") + _ret = 505; + else if (_method != "GET" && _method != "POST" + && _method != "DELETE") + _ret = 405; + else if (isFile(_fullURI) != 0 && isDir(_fullURI) != 0) + _ret = 404; + return (_ret); +} + +int Request::parseHeaderfield(std::string str) +{ + int distance; + std::string key; + std::string value; + + distance = str.find(":"); + if (distance < 0 && str != "\r") + return 400; + key = str.substr(0, distance); + std::transform(key.begin(), key.end(), key.begin(), ::tolower); + value = str.erase(0, distance + 1); + if (_headerField.find(key) != _headerField.end()) + { + std::cout << RED << "ERROR: double header-field" << ZERO_C << std::endl; + } + else + { + value = value.erase(0, value.find_first_not_of(WHITESPACE)); + value = value.substr(0, value.find_last_not_of(WHITESPACE) + 1); + _headerField[key] = value; + } + return 200; +} + +int Request::parseRequest(void) +{ + std::string line; + std::stringstream buffStream; + + buffStream << _data; + _ret = 200; + while (std::getline(buffStream, line, '\n') && !badCode(_ret)) + { + if (_row == 0) + _ret = parseStartLine(line); + else + _ret = parseHeaderfield(line); + _row++; + } + if (!badCode(_ret)) + copyFromMap(); + return (_ret); +} + +//-------------------------------------------------Utils--------------------------------------- + + +void Request::copyFromMap() +{ + _host = _headerField.find("host")->second; +} + +bool Request::badCode(int code) +{ + if (code == 200) + return (false); + return true; +} + +int Request::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 Request::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); +} + +void Request::clear(void) +{ + _ret = 200; + _row = 0; + _URI = ""; + _body = ""; + _host = ""; + _query = ""; + _method = ""; + _fullURI = ""; + _version = ""; + _location = ""; + _headerField.clear(); + _data = NULL; + _config = NULL; +} + +Request::~Request() +{ +} diff --git a/src/Header/Request.hpp b/src/Header/Request.hpp new file mode 100644 index 0000000..753cd77 --- /dev/null +++ b/src/Header/Request.hpp @@ -0,0 +1,67 @@ +#ifndef REQUEST_HPP +#define REQUEST_HPP + +#include "ServerConfig.hpp" +#include "webserv.hpp" + + +class Request +{ +private: + char *_data; + + int _ret; + int _row; + + std::string _URI; + std::string _body; + std::string _host; + std::string _query; + std::string _method; + std::string _fullURI; + std::string _version; + std::string _location; + std::map _headerField; + + ServerConfig *_config; + +public: + std::string getURI(void); + std::string getBody(void); + std::string getHost(void); + std::string getQuery(void); + std::string getMethod(void); + std::string getFullUri(void); + std::string getVersion(void); + std::string getLocation(void); + ServerConfig *getConfig(void); + int getCode(void); + std::map getHeaderFields(void); + + void setConfig(ServerConfig *config); + void setData(char *); + void setData(char *, ServerConfig *); + +public: + + Request(); + Request(char *str); + int parseStartLine(std::string); + int parseHeaderfield(std::string); + int parseRequest(void); + void parseURI(std::string); + void printHeaderInfo(void); + + bool badCode(int); + int isDir(std::string path); + int isFile(std::string path); + bool autoindexOn(void); + void copyFromMap(void); + void clear(void); + + ~Request(); +}; + + + +#endif \ No newline at end of file diff --git a/src/Header/Respons.cpp b/src/Header/Respons.cpp new file mode 100644 index 0000000..05f06dd --- /dev/null +++ b/src/Header/Respons.cpp @@ -0,0 +1,177 @@ +#include "Respons.hpp" + +//-------------------------------------------------Constructor--------------------------------------- + +Respons::Respons() +{ + initErrorCode(); +} + +//-------------------------------------------------GET/SET--------------------------------------- + +std::string Respons::getHeader(void) +{ + return (_header); +} +std::string Respons::getBody(void) +{ + return (_body); +} + +void Respons::setData(Request request, ServerConfig *config) +{ + _request = request; + _config = config; +} + +//-------------------------------------------------File--------------------------------------- + +void Respons::OpenResponsFile(const char *path) +{ + std::stringstream ss; + char buf[BUFFSIZE + 1] = {0}; + std::ifstream file(path); + + if (file.is_open()) + { + while (!file.eof()) + { + file.read(buf, BUFFSIZE); + ss << buf; + memset(buf, 0, BUFFSIZE + 1); + } + _body = ss.str(); + file.close(); + } + else + _body = getErrorPage(403); +} + +void Respons::generate() +{ + if (_request.badCode(_request.getCode())) + invalidHeader(); + else if (_request.getMethod() == "GET") + methodGet(); + // else if (_request.getMethod() == "POST") + // methodPost(); + // else + // methodDelete(); +} + +//-------------------------------------------------GET/SET--------------------------------------- + +void Respons::invalidHeader(void) +{ + std::stringstream ss; + std::string tmp; + //header + ss << _request.getVersion() << " " << _request.getCode() << " " << getReasonPhrase(_request.getCode()) << "\r\nContent-Type: text/html\r\n\r\n"; + _header = ss.str(); + + //body + _body = getErrorPage(_request.getCode()); + std::cout << RED << "Invalid Header method called\n" << ZERO_C; +} + +void Respons::methodGet(void) +{ + std::stringstream ss; + std::string tmp; + //header + ss << _request.getVersion() << " " << _request.getCode() << " " << getReasonPhrase(_request.getCode()) << "\r\nContent-Type: text/html\r\n\r\n"; + _header = ss.str(); + //body + if (!_request.badCode(_request.getCode()) && _request.isDir(_request.getFullUri()) == 0) + _body = Autoindex::getPage(_request.getURI(), _request.getFullUri(), _request.getHost()); + else if (!_request.badCode(_request.getCode())) + OpenResponsFile(_request.getFullUri().c_str()); + else + _body = getErrorPage(_request.getCode()); + std::cout << GREEN << "GET method called\n" << ZERO_C; + +} + +//-------------------------------------------------GET/SET--------------------------------------- + +void Respons::initErrorCode(void) +{ + _errorCode["100"] = "Continue"; + _errorCode["101"] = "Switching Protocols"; + _errorCode["200"] = "OK"; + _errorCode["201"] = "Created"; + _errorCode["202"] = "Accepted"; + _errorCode["203"] = "Non-Authoritative Information"; + _errorCode["204"] = "No Content"; + _errorCode["205"] = "Reset Content"; + _errorCode["206"] = "Partial Content"; + _errorCode["300"] = "Multiple Choices"; + _errorCode["301"] = "Moved Permanently"; + _errorCode["302"] = "Found"; + _errorCode["303"] = "See Other"; + _errorCode["304"] = "Not Modified"; + _errorCode["305"] = "Use Proxy"; + _errorCode["306"] = "(Unused)"; + _errorCode["307"] = "Temporary Redirect"; + _errorCode["400"] = "Bad Request"; + _errorCode["401"] = "Unauthorized"; + _errorCode["402"] = "Payment Required"; + _errorCode["403"] = "Forbidden"; + _errorCode["404"] = "Not Found"; + _errorCode["405"] = "Method Not Allowed"; + _errorCode["406"] = "Not Acceptable"; + _errorCode["407"] = "Proxy Authentication Required"; + _errorCode["408"] = "Request Timeout"; + _errorCode["409"] = "Conflict"; + _errorCode["410"] = "Gone"; + _errorCode["411"] = "Length Required"; + _errorCode["412"] = "Precondition Failed"; + _errorCode["413"] = "Request Entity Too Large"; + _errorCode["414"] = "Request-URI Too Long"; + _errorCode["415"] = "Unsupported Media Type"; + _errorCode["416"] = "Requested Range Not Satisfiable"; + _errorCode["417"] = "Expectation Failed"; + _errorCode["500"] = "Internal Server Error"; + _errorCode["501"] = "Not Implemented"; + _errorCode["502"] = "Bad Gateway"; + _errorCode["503"] = "Service Unavailable"; + _errorCode["504"] = "Gateway Timeout"; + _errorCode["505"] = "HTTP Version Not Supported"; +} + +std::string Respons::getReasonPhrase(std::string code) +{ + std::map::iterator it; + + it = _errorCode.find(code); + return (it->second); +} + +std::string Respons::getReasonPhrase(int code) +{ + std::stringstream ss; + std::string nbr; + std::map::iterator it; + + ss << code; + nbr = ss.str(); + it = _errorCode.find(nbr); + return (it->second); +} + +std::string Respons::getErrorPage(int code) +{ + std::stringstream ss; + std::string Page; + + ss << "" << code <<" "<< getReasonPhrase(code) <<"" + <<"

" << code <<" " << getReasonPhrase(code) <<"

" + << "
poheck/1.0.0 (KDE)
"; + Page = ss.str(); + return (Page); + } + + +Respons::~Respons() +{ +} diff --git a/src/Header/Respons.hpp b/src/Header/Respons.hpp new file mode 100644 index 0000000..9bcdeb4 --- /dev/null +++ b/src/Header/Respons.hpp @@ -0,0 +1,45 @@ +#ifndef RESPONS_HPP +#define RESPONS_HPP + +#include "webserv.hpp" +#include "Request.hpp" +#include "Autoindex.hpp" + +class Respons +{ +private: + std::string _body; + std::string _header; + Request _request; + ServerConfig *_config; + +private: + std::map _errorCode; + +private: + void methodGet(void); + // void methodPost(void); + // void methodDelete(void); + void invalidHeader(void); + +public: + std::string getHeader(void); + std::string getBody(void); + std::string getReasonPhrase(std::string); + std::string getReasonPhrase(int); + std::string getErrorPage(int code); + + + void setData(Request, ServerConfig *); +public: + void OpenResponsFile(const char *path); + void initErrorCode(void); + void generate(); + Respons(); + ~Respons(); + +}; + + + +#endif \ No newline at end of file diff --git a/src/Server/Server.cpp b/src/Server/Server.cpp index 5604ddc..1e7b648 100644 --- a/src/Server/Server.cpp +++ b/src/Server/Server.cpp @@ -37,25 +37,11 @@ void Server::readConfig(void) arr = root->find("server")->second->getMapArray(); it = arr->begin(); - /* while (it != arr->end()) */ - /* { */ - /* std::cout << BLUE << *it << std::endl; */ - /* map = *it; */ - - /* it1 = map->begin(); */ - /* while (it1 != map->end()) */ - /* { */ - /* std::cout << TURGUOISE << it1->first << it1->second << ZERO_C << std::endl; */ - /* ++it1; */ - /* } */ - - - /* ++it; */ - /* } */ - - - - + while (it != arr->end()) + { + _configs.push_back(new ServerConfig(*it)); + ++it; + } } void Server::setupConfig(void) @@ -97,6 +83,11 @@ void Server::add_to_epoll_list(int fd) void Server::start(void) { + Socket serverSocket(AF_INET, SOCK_STREAM, 0, _port, "127.0.0.1"); + char buff[BUFFSIZE + 1] = {0}; + Header header; + int fd_accept; + int code; Socket server_sock(AF_INET, SOCK_STREAM, 0, _port, "127.0.0.1"); char buf[BUFFSIZE + 1] = {0}; @@ -183,7 +174,15 @@ void Server::start(void) void Server::end(void) { + std::vector::iterator pri; + pri = _configs.begin(); + while (pri != _configs.end()) + { + (*pri)->printFields(); + delete *pri; + pri++; + } } //----------------------------------------------Other------------------------------------------------------------------------------------------------ void Server::checkError(int fd, std::string str) diff --git a/src/Server/ServerConfig.cpp b/src/Server/ServerConfig.cpp index 9661161..947df84 100644 --- a/src/Server/ServerConfig.cpp +++ b/src/Server/ServerConfig.cpp @@ -2,12 +2,15 @@ ServerConfig::ServerConfig() { + ret = 0; } -// ServerConfig::ServerConfig(TOMLMap *map) -// { -// _root = map; -// } +ServerConfig::ServerConfig(TOMLMap *map) +{ + ret = 0; + server = map; + fillFields(); +} //--------------------------------------------------GET/SET--------------------------------------- std::string ServerConfig::getServerName(void) @@ -40,10 +43,10 @@ std::map ServerConfig::getErrorPages(void) return (_errorPages); } -// TOMLMap ServerConfig::*getRoot(void) -// { -// return (this->_root); -// } +TOMLMap *ServerConfig::getRoot(void) +{ + return (server); +} void ServerConfig::setServerName(std::string name) { @@ -75,24 +78,229 @@ void ServerConfig::setLocations(std::vector locations) _locations = locations; } -// void ServerConfig::setRoot(TOMLMap * data) -// { -// _root = data; -// } +void ServerConfig::setRoot(TOMLMap * data) +{ + server = data; +} +//--------------------------------------------------Parse-Config--------------------------------------- + +int ServerConfig::putBodySizeLimit(toml_node *node) +{ + if (node->get_type() != toml_node::NUM) + return (1); + _clientBodySize = node->getNum(); + return (0); +} +int ServerConfig::putErrorPage(toml_node *node) +{ + if (node->get_type() != toml_node::MAP) + return (1); + TOMLMap *map = node->getMap(); + TOMLMap::iterator it; + std::string s; + + it = map->begin(); + while (it != map->end()) + { + if (it->second->get_type() != toml_node::STRING) + return (1); + s = it->first; + _errorPages[atoi(s.c_str())] = *it->second->getString(); + ++it; + } + return (0); +} +int ServerConfig::putHost(toml_node *node) +{ + if (node->get_type() != toml_node::STRING) + return (1); + _host = *node->getString(); + return (0); +} +int ServerConfig::putName(toml_node *node) +{ + if (node->get_type() != toml_node::STRING) + return (1); + _serverName = *node->getString(); + return (0); +} +int ServerConfig::putPort(toml_node *node) +{ + if (node->get_type() != toml_node::NUM) + return (1); + _port = node->getNum(); + return (0); +} +int ServerConfig::putLocation(toml_node *node) +{ + if (node->get_type() != toml_node::MAPARRAY) + return (1); + + TOMLMapArray *arr = node->getMapArray(); + TOMLMapArray::iterator it = arr->begin(); + TOMLMap *map; + TOMLMap::iterator it1; + location tmp; + TOMLArray::iterator it2; + TOMLArray Array; + + std::string str; + while (it != arr->end()) + { + map = *it; + it1 = map->begin(); + while (it1 != map->end()) + { + if (it1->first == "location") + { + if (it1->second->get_type() != toml_node::STRING) + return (1); + tmp.location = *it1->second->getString(); + } + else if (it1->first == "root") + { + if (it1->second->get_type() != toml_node::STRING) + return (1); + tmp.root = *it1->second->getString(); + } + else if (it1->first == "autoindex") + { + if (it1->second->get_type() != toml_node::BOOL) + return (1); + tmp.autoindex = it1->second->getBool(); + } + else if (it1->first == "upload_accept") + { + if (it1->second->get_type() != toml_node::BOOL) + return (1); + tmp.uploadAccept = it1->second->getBool(); + } + else if (it1->first == "upload_dir") + { + if (it1->second->get_type() != toml_node::STRING) + return (1); + tmp.uploadDir = *it1->second->getString(); + } + else if (it1->first == "directory_file") + { + if (it1->second->get_type() != toml_node::STRING) + return (1); + tmp.directoryFile = *it1->second->getString(); + } + else if (it1->first == "methods") + { + if (it1->second->get_type() != toml_node::ARRAY) + return (1); + Array = *it1->second->getArray(); + it2 = Array.begin(); + while (it2 != Array.end()) + { + if ((*it2)->get_type() != toml_node::STRING) + return (1); + tmp.methods.push_back(*((*it2)->getString())); + ++it2; + } + + } + else if (it1->first == "redirect") + { + if (it1->second->get_type() != toml_node::ARRAY) + return (1); + Array = *it1->second->getArray(); + it2 = Array.begin(); + str = *(*it2)->getString(); + ++it2; + tmp.redirect[atoi(str.c_str())] = *(*it2)->getString(); + } + else + std::cout << RED << it1->first << ZERO_C << std::endl; + it1++; + } + _locations.push_back(tmp); + memset(&tmp, 0, sizeof(tmp)); + it++; + } + return (0); +} + +int ServerConfig::identify(TOMLMap::iterator it) +{ + if (it->first == "body_size_limit") + putBodySizeLimit(it->second); + else if (it->first == "error_page") + putErrorPage(it->second); + else if (it->first == "host") + putHost(it->second); + else if (it->first == "location") + putLocation(it->second); + else if (it->first == "name") + putName(it->second); + else if (it->first == "port") + putPort(it->second); + else + return (1); + return (0); +} + void ServerConfig::fillFields(void) { - // TOMLMap *tmp = _root; - // TOMLMap::iterator it; - // it = tmp->begin(); + TOMLMap::iterator block; - // while (it != tmp->end()) - // { - // std::cout << it->first << std::endl; - // } - + block = server->begin(); + while (block != server->end() && ret == 0) + { + ret = identify(block); + ++block; + } +} + +void ServerConfig::printFields(void) +{ + std::vector::iterator it; + std::map::iterator it1; + std::vector::iterator it2; + std::map::iterator it3; + + 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; + while (it != _locations.end()) + { + std::cout << PINK << "------------------------------------------------\n"; + std::cout << YELLOW << "location " << BLUE << (*it).location <first << " " << BLUE << it3->second << std::endl; + ++it; + std::cout << PINK << "------------------------------------------------\n"; + } + std::cout << GREEN << "error pages" << std::endl; + while (it1 != _errorPages.end()) + { + std::cout << YELLOW << it1->first << " " << BLUE << it1->second << std::endl; + ++it1; + } + std::cout << RED << "-------------------------Server-End------------------------------------\n" << ZERO_C; } ServerConfig::~ServerConfig() diff --git a/src/Server/ServerConfig.hpp b/src/Server/ServerConfig.hpp index bf5eedb..39be2d4 100644 --- a/src/Server/ServerConfig.hpp +++ b/src/Server/ServerConfig.hpp @@ -2,6 +2,7 @@ #define SERVERCONFIG_HPP #include "webserv.hpp" +#include "parse.hpp" struct location { @@ -17,8 +18,10 @@ struct location class ServerConfig { +public: + int ret; private: - // TOMLMap *_root; + TOMLMap *server; std::string _serverName; std::string _host; int _port; @@ -34,7 +37,7 @@ public: void setClientBodySize(int); void setErrorPages(std::map); void setLocations(std::vector); - // void setRoot(TOMLMap *); + void setRoot(TOMLMap *); std::string getServerName(void); std::string getHost(void); @@ -42,13 +45,23 @@ public: int getClientBodySize(void); std::vector getLocations(void); std::map getErrorPages(void); - // TOMLMap *getRoot(void); + TOMLMap *getRoot(void); public: ServerConfig(); - // ServerConfig(TOMLMap *root); - + ServerConfig(TOMLMap *root); +private: + int identify(TOMLMap::iterator it); + int putBodySizeLimit(toml_node *); + int putErrorPage(toml_node *); + int putHost(toml_node *); + int putName(toml_node *); + int putPort(toml_node *); + int putLocation(toml_node *); + +public: void fillFields(void); + void printFields(void); ~ServerConfig(); }; diff --git a/src/main.cpp b/src/main.cpp index aba9ca4..31ee019 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,6 +12,7 @@ int main(int argc, char **argv) server.readConfig(); server.setupConfig(); server.start(); + // server.end(); return (0);