mirror of
https://github.com/3lswear/webserv.git
synced 2025-10-28 21:07:59 +03:00
add error handling(header class)
This commit is contained in:
@@ -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 *);
|
||||
|
||||
@@ -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"
|
||||
|
||||
274
src/Header.cpp
274
src/Header.cpp
@@ -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;
|
||||
|
||||
@@ -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------------------
|
||||
|
||||
Reference in New Issue
Block a user