add error handling(header class)

This commit is contained in:
Talyx
2022-01-18 21:05:07 +03:00
parent 99e3faf5b5
commit c89c65f354
4 changed files with 245 additions and 100 deletions

View File

@@ -7,32 +7,43 @@ class Header
{
private:
int _row;
int _ret;
int _fd;
char *_buff;
std::string _method;
std::string _version;
std::string _URI;
std::string _query;
std::string _fileToSend;
std::map<std::string, std::string> _headerField;
std::map<std::string, std::string> _errorCode;
public:
enum REQ
{
GET,
POST,
DELETE
};
public:
std::map<std::string, std::string> getRequest(void);
std::map<std::string , std::string> getRequest(void);
std::string getMethod(void);
std::string getURI(void);
std::string getReasonPhrase(std::string);
std::string getReasonPhrase(int);
std::string getErrorPage(int code);
void setRawData(char *);
void setFd(int);
int getFd(void);
void initErrorCode(void);
int checkURI(void);
int isFile(std::string);
int isDir(std::string);
void OpenResponsFile(const char *path);
int parseStartLine(std::string);
int parseHeaderfield(std::string);
void printHeaderInfo(void);
int parseRequest(void);
int sendRespons(int fd);
int sendHeader(int fd);
void clear(void);
Header();
Header(char *);

View File

@@ -27,7 +27,10 @@
#include <vector>
#include <sstream>
#include <string>
#include <string.h>
#include <sys/stat.h>
#include <map>
#include <fstream>
#include "Socket.hpp"
#include "Server.hpp"
#include "Header.hpp"

View File

@@ -3,63 +3,36 @@
Header::Header()
{
this->_row = 0;
this->_fd = -1;
initErrorCode();
}
// std::string** Header::initErrorCode(void)
// {
// std::string HttpCode [41][2]= {{"100", "Continue"},
// {"101", "Switching Protocols"},
// {"200", "OK"},
// {"201", "Created"},
// {"202", "Accepted"},
// {"203", "Non-Authoritative Information"},
// {"204", "No Content"},
// {"205", "Reset Content"},
// {"206", "Partial Content"},
// {"300", "Multiple Choices"},
// {"301", "Moved Permanently"},
// {"302", "Found"},
// {"303", "See Other"},
// {"304", "Not Modified"},
// {"305", "Use Proxy"},
// {"306", "(Unused)"},
// {"307", "Temporary Redirect"},
// {"400", "Bad Request"},
// {"401", "Unauthorized"},
// {"402", "Payment Required"},
// {"403", "Forbidden"},
// {"404", "Not Found"},
// {"405", "Method Not Allowed"},
// {"406", "Not Acceptable"},
// {"407", "Proxy Authentication Required"},
// {"408", "Request Timeout"},
// {"409", "Conflict"},
// {"410", "Gone"},
// {"411", "Length Required"},
// {"412", "Precondition Failed"},
// {"413", "Request Entity Too Large"},
// {"414", "Request-URI Too Long"},
// {"415", "Unsupported Media Type"},
// {"416", "Requested Range Not Satisfiable"},
// {"417", "Expectation Failed"},
// {"500", "Internal Server Error"},
// {"501", "Not Implemented"},
// {"502", "Bad Gateway"},
// {"503", "Service Unavailable"},
// {"504", "Gateway Timeout"},
// {"505", "HTTP Version Not Supported"}};
// return (HttpCode);
// }
Header::Header(char *str)
{
this->_row = 0;
this->_fd = -1;
this->_buff = str;
initErrorCode();
parseRequest();
}
//-------------------------------------------------GET/SET---------------------------------------
std::string Header::getErrorPage(int code)
{
std::stringstream ss;
std::string Page;
ss << "<html><head><title>" << code <<" "<< getReasonPhrase(code) <<"</title></head><body>"
<<"<center><h1>" << code <<" " << getReasonPhrase(code) <<"</h1></center> "
<< "<hr><center>poheck/1.0.0 (KDE)</center></body></html>";
Page = ss.str();
return (Page);
}
std::map<std::string, std::string> Header::getRequest(void)
{
return (this->_headerField);
@@ -75,11 +48,22 @@ std::string Header::getURI(void)
return _URI;
}
int Header::getFd(void)
{
return _fd;
}
void Header::setRawData(char *str)
{
this->_buff = str;
}
//--------------------------------------------------
void Header::setFd(int fd)
{
this->_fd = fd;
}
//-------------------------------------------------Parsing---------------------------------------
int Header::parseStartLine(std::string str)
{
@@ -91,14 +75,17 @@ int Header::parseStartLine(std::string str)
str = str.erase(0 , str.find(" ") + 1);
_version = str;
_version.erase(_version.find_last_not_of(" \n\r\t") + 1);
if (_URI == "/")
_URI = "www/index2.html";
else
_URI = HOME + _URI;
if (_version != "HTTP/1.1")
return (505);
else if (_method != "GET" && _method != "POST" && _method != "DELETE")
return (405);
else if (checkURI() < 0)
{
if (isDir(_URI) == 0)
return (403);
else
return (404);
}
return 200;
}
@@ -127,28 +114,200 @@ int Header::parseHeaderfield(std::string str)
int Header::parseRequest(void)
{
std::string line;
int ret;
std::stringstream buffStream;
buffStream << _buff;
ret = 200;
while (std::getline(buffStream, line, '\n') && ret == 200)
_ret = 200;
while (std::getline(buffStream, line, '\n') && _ret == 200)
{
if (_row == 0)
ret = parseStartLine(line);
_ret = parseStartLine(line);
else
ret = parseHeaderfield(line);
_ret = parseHeaderfield(line);
_row++;
}
return (200);
return (_ret);
}
//-------------------------------------------------FILE---------------------------------------
int Header::checkURI(void)
{
const char *path;
std::string tmp;
int pos;
tmp = _URI;
pos = _URI.find("?");
if (pos > 0)
{
_URI = tmp.substr(0, pos);
_query = tmp.erase(0, pos + 1);
}
_URI = HOME + _URI;
path = _URI.c_str();
if (isFile(_URI) < 0)
return (-1);
return (0);
}
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::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);
}
_fileToSend = ss.str();
file.close();
}
else
_fileToSend = getErrorPage(403);
}
//-------------------------------------------------SEND---------------------------------------
int Header::sendHeader(int fd)
{
std::stringstream ss;
std::string tmp;
const char *header;
ss << _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);
}
int Header::sendRespons(int fd)
{
sendHeader(fd);
if (_ret == 200)
OpenResponsFile(_URI.c_str());
else
_fileToSend = getErrorPage(_ret);
send(fd, _fileToSend.c_str(), _fileToSend.length(), 0);
return (0);
}
//-------------------------------------------------Error---------------------------------------
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<std::string, std::string>::iterator it;
it = _errorCode.find(code);
return (it->second);
}
std::string Header::getReasonPhrase(int code)
{
std::stringstream ss;
std::string nbr;
std::map<std::string, std::string>::iterator it;
ss << code;
nbr = ss.str();
it = _errorCode.find(nbr);
return (it->second);
}
//-------------------------------------------------Other---------------------------------------
void Header::printHeaderInfo(void)
{
std::map<std::string, std::string>::iterator it;
std::cout << PINK << "request method = " << _method << ZERO_C << std::endl;
std::cout << PINK << "request URI = " << _URI << ZERO_C << std::endl;
std::cout << PINK << "request query = " << _query << ZERO_C << std::endl;
std::cout << PINK << "request http versioin = " << _version << ZERO_C << std::endl;
std::cout << PINK << "request rows = " << _row << ZERO_C << std::endl;
std::cout << YELLOW << "request header:\n" << _buff << ZERO_C << std::endl;
@@ -163,6 +322,7 @@ void Header::printHeaderInfo(void)
void Header::clear(void)
{
_fd = -1;
_method = "";
_row = 0;
_buff = NULL;

View File

@@ -14,37 +14,6 @@ Server::Server(std::string path)
//----------------------------------------------Send--------------------------------------------------------------------------------------------
void Server::sendHeader(Header head, int fd)
{
std::string tmp;
const char *header;
tmp = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
header = tmp.c_str();
std::cout << TURGUOISE << "Send Header\n" << YELLOW << tmp << ZERO_C;
send(fd, header, tmp.length(), 0);
(void)head;
}
void Server::sendRespons(Header head, int fd)
{
std::string str = head.getURI();
const char *path = str.c_str();
std::ifstream file(path);
char buff[BUFFSIZE + 1] = {0};
if (!file.good())
{
file.open("www/index2.html");
}
sendHeader(head, fd);
while (!file.eof())
{
file.read(buff, BUFFSIZE);
send(fd, buff, file.gcount(), 0);
}
(void)path;
}
//----------------------------------------------Configuration-----------------------------------------------------------------------------------
void Server::readConfig(void)
{
@@ -79,6 +48,7 @@ void Server::start(void)
char buff[BUFFSIZE + 1] = {0};
Header header;
int fd_accept;
int code;
checkError(serverSocket.init(MAX_CLIENT), "Socket init");
fd_accept = accept(serverSocket.getSocketFd(),
@@ -87,9 +57,10 @@ void Server::start(void)
checkError(recv(fd_accept, buff, BUFFSIZE, 0), "Receive msg from client");
std::cout << TURGUOISE << "Receive Header" << ZERO_C << std::endl;
header.setRawData(buff);
header.parseRequest();
code = header.parseRequest();
header.printHeaderInfo();
sendRespons(header, fd_accept);
header.sendRespons(fd_accept);
std::cout << BLUE << header.getReasonPhrase(code) << ZERO_C << std::endl;
close(fd_accept);
close(serverSocket.getSocketFd());
//-----------------------------------------------попытка добавить epoll------------------