From 5f9fec9568dad9a88b565e4f40f20f0ee8048f35 Mon Sep 17 00:00:00 2001 From: y-syo Date: Mon, 17 Mar 2025 14:33:38 +0100 Subject: [PATCH] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D=20wip:?= =?UTF-8?q?=20work=20in=20progress,=20not=20done=20yet.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/requests/Errors.hpp | 132 +++++++++++++++++++++++++ includes/requests/default.hpp | 3 +- src/main.cpp | 2 +- src/requests_handling/Errors.cpp | 100 +++++++++++++++++++ src/requests_handling/HttpRequests.cpp | 79 ++++++++++++++- src/requests_handling/HttpResponse.cpp | 8 +- 6 files changed, 316 insertions(+), 8 deletions(-) create mode 100644 includes/requests/Errors.hpp create mode 100644 src/requests_handling/Errors.cpp diff --git a/includes/requests/Errors.hpp b/includes/requests/Errors.hpp new file mode 100644 index 0000000..225293d --- /dev/null +++ b/includes/requests/Errors.hpp @@ -0,0 +1,132 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Errors.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mmoussou +#include + +#include + +namespace webserv { +namespace http { + +/* + * DOES NOT WORK + * still need to do uh things but base is done at least :D +*/ + +class Errors { +public: + static http::Response &getRequest(int error_code); + static void setEntry(const std::string &key, int value); + +private: + static std::map populateMessages(); + + static std::map message; + static std::map set_error_pages; + +}; + +/*std::map Errors::populateMessages() +{ + std::map m; + + m[100] = "Continue"; + m[101] = "Switching Protocols"; + m[102] = "Processing"; + m[103] = "Early Hints"; + m[200] = "OK"; + m[201] = "Created"; + m[202] = "Accepted"; + m[203] = "Non-Authoritative Information"; + m[204] = "No Content"; + m[205] = "Reset Content"; + m[206] = "Partial Content"; + m[207] = "Multi-Status"; + m[208] = "Already Reported"; + m[226] = "IM Used"; + m[300] = "Multiple Choices"; + m[301] = "Moved Permanently"; + m[302] = "Found"; + m[303] = "See Other"; + m[304] = "Not Modified"; + m[305] = "Use Proxy"; + m[306] = "Switch Proxy"; + m[307] = "Temporary Redirect"; + m[308] = "Permanent Redirect"; + m[400] = "Bad Request"; + m[401] = "Unauthorized"; + m[402] = "Payment Required"; + m[403] = "Forbidden"; + m[404] = "Not Found"; + m[405] = "Method Not Allowed"; + m[406] = "Not Acceptable"; + m[407] = "Proxy Authentication Required"; + m[408] = "Request Timeout"; + m[409] = "Conflict"; + m[410] = "Gone"; + m[411] = "Length Required"; + m[412] = "Precondition Failed"; + m[413] = "Payload Too Large"; + m[414] = "URI Too Long"; + m[415] = "Unsupported Media Type"; + m[416] = "Range Not Satisfiable"; + m[417] = "Expectation Failed"; + m[418] = "I'm a teapot"; + m[420] = "Method Failure"; + m[421] = "Misdirected Request"; + m[422] = "Unprocessable Entity"; + m[423] = "Locked"; + m[424] = "Failed Dependency"; + m[426] = "Upgrade Required"; + m[428] = "Precondition Required"; + m[429] = "Too Many Requests"; + m[431] = "Request Header Fields Too Large"; + m[451] = "Unavailable For Legal Reasons"; + m[500] = "Internal Server error"; + m[501] = "Not Implemented"; + m[502] = "Bad Gateway"; + m[503] = "Service Unavailable"; + m[504] = "gateway Timeout"; + m[505] = "Http version not supported"; + m[506] = "Varient Also negotiate"; + m[507] = "Insufficient Storage"; + m[508] = "Loop Detected"; + m[510] = "Not Extended"; + m[511] = "Network Authentication Required"; + + return m; +} + +std::map Errors::message = Errors::populateMessages(); + +std::map Errors::set_error_pages; + +http::Response &Errors::getRequest(int error_code) +{ + http::Response *result = new http::Response; + + if (Errors::set_error_pages.find(error_code) != Errors::set_error_pages.end()) + result->setBody(Errors::set_error_pages[error_code]); + else + result->setBody("

" + Errors::message[error_code] + "

"); + return (*result); +}*/ + +} // -namespace http +} // -namespace webserv + +#endif // __WEBSERV_REQUESTS_ERRORS_HPP__ diff --git a/includes/requests/default.hpp b/includes/requests/default.hpp index 3c8763d..82636b6 100644 --- a/includes/requests/default.hpp +++ b/includes/requests/default.hpp @@ -6,7 +6,7 @@ /* By: mmoussou #include #include diff --git a/src/main.cpp b/src/main.cpp index a17cea2..a7a18f4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,7 +6,7 @@ /* By: mmoussou + +using namespace webserv; + +http::Response &http::Errors::getRequest(int error_code) +{ + http::Response *result = new http::Response; + + if (http::Errors::set_error_pages.find(error_code) != http::Errors::set_error_pages.end()) + result->setBody(Errors::set_error_pages[error_code]); + else + result->setBody("

" + http::Errors::message[error_code] + "

"); + return (*result); +} + +std::map http::Errors::message = Errors::populateMessages(); +std::map http::Errors::set_error_pages; + +std::map http::Errors::populateMessages() +{ + std::map m; + + m[100] = "Continue"; + m[101] = "Switching Protocols"; + m[102] = "Processing"; + m[103] = "Early Hints"; + m[200] = "OK"; + m[201] = "Created"; + m[202] = "Accepted"; + m[203] = "Non-Authoritative Information"; + m[204] = "No Content"; + m[205] = "Reset Content"; + m[206] = "Partial Content"; + m[207] = "Multi-Status"; + m[208] = "Already Reported"; + m[226] = "IM Used"; + m[300] = "Multiple Choices"; + m[301] = "Moved Permanently"; + m[302] = "Found"; + m[303] = "See Other"; + m[304] = "Not Modified"; + m[305] = "Use Proxy"; + m[306] = "Switch Proxy"; + m[307] = "Temporary Redirect"; + m[308] = "Permanent Redirect"; + m[400] = "Bad Request"; + m[401] = "Unauthorized"; + m[402] = "Payment Required"; + m[403] = "Forbidden"; + m[404] = "Not Found"; + m[405] = "Method Not Allowed"; + m[406] = "Not Acceptable"; + m[407] = "Proxy Authentication Required"; + m[408] = "Request Timeout"; + m[409] = "Conflict"; + m[410] = "Gone"; + m[411] = "Length Required"; + m[412] = "Precondition Failed"; + m[413] = "Payload Too Large"; + m[414] = "URI Too Long"; + m[415] = "Unsupported Media Type"; + m[416] = "Range Not Satisfiable"; + m[417] = "Expectation Failed"; + m[418] = "I'm a teapot"; + m[420] = "Method Failure"; + m[421] = "Misdirected Request"; + m[422] = "Unprocessable Entity"; + m[423] = "Locked"; + m[424] = "Failed Dependency"; + m[426] = "Upgrade Required"; + m[428] = "Precondition Required"; + m[429] = "Too Many Requests"; + m[431] = "Request Header Fields Too Large"; + m[451] = "Unavailable For Legal Reasons"; + m[500] = "Internal Server error"; + m[501] = "Not Implemented"; + m[502] = "Bad Gateway"; + m[503] = "Service Unavailable"; + m[504] = "gateway Timeout"; + m[505] = "Http version not supported"; + m[506] = "Varient Also negotiate"; + m[507] = "Insufficient Storage"; + m[508] = "Loop Detected"; + m[510] = "Not Extended"; + m[511] = "Network Authentication Required"; + + return m; +} diff --git a/src/requests_handling/HttpRequests.cpp b/src/requests_handling/HttpRequests.cpp index 3f04829..6582ad8 100644 --- a/src/requests_handling/HttpRequests.cpp +++ b/src/requests_handling/HttpRequests.cpp @@ -6,7 +6,7 @@ /* By: mmoussou _protocol); response.setStatusCode(200); response.setStatusText("OK"); - response.addHeader("Content-Type", "text/html"); + response.addHeader("Content-Type", "text/html"); // TODO: change it to check the file extension and set it to the corresponding MIME or text/plain if unkown. we will only implement the important MIME types in the Mozilla documentation because https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types/Common_types + + std::ifstream file_end(this->_target.c_str(), std::ios::binary | std::ios::ate); + std::stringstream length; + length << (file_end.tellg() - file.tellg()); + std::cout << length.str(); + response.addHeader("Content-Length", length.str()); + response.setBody(std::string((std::istreambuf_iterator(file)), std::istreambuf_iterator())); } catch (...) @@ -204,14 +211,15 @@ http::Response http::Delete::execute(void) if (std::remove(this->_target.c_str())) throw; response.setProtocol(this->_protocol); - response.setStatusCode(204); + response.setStatusCode(204); // this cool dude on the internet said i should not do that so i'll change it https://blog.ploeh.dk/2013/04/30/rest-lesson-learned-avoid-204-responses/ response.setStatusText("No Content"); time_t now = std::time(NULL); response.addHeader("Date", std::string(std::ctime(&now))); } catch (...) { - // TODO: replace with a predefined array of error pages + // TODO: check errno value and get corresponding error page, check for corresponding error code : https://cdn.discordapp.com/attachments/784779058407014403/1350841524778307586/image.png?ex=67d8dd74&is=67d78bf4&hm=c030468d3862627d6402bf200960d1a15249ba2f8dac772af3283b368a77f2f5& + response.setProtocol(this->_protocol); response.setStatusCode(404); response.setStatusText("Not Found"); @@ -222,3 +230,66 @@ http::Response http::Delete::execute(void) return (response); } +// ------------------------------------------------------------------ + +http::Post::Post(void) +{ +} + +http::Post::Post(std::string &data) +{ + this->parse(data); +} + +void http::Post::parse(std::string const &data) +{ + std::istringstream stream(data); + std::string line; + + if (std::getline(stream, line)) + { + std::istringstream line_stream(line); + line_stream >> this->_method >> this->_target >> this->_protocol; + this->_target.insert(this->_target.begin(), '.'); + } + + while (std::getline(stream, line) && line != "\r") + { + size_t delimiter_index = line.find(':'); + if (delimiter_index != std::string::npos) + { + std::string key = line.substr(0, delimiter_index); + std::string value = line.substr(delimiter_index + 2); + this->_headers.insert(std::make_pair(key, value)); + } + } + + std::ostringstream body_stream; + while (std::getline(stream, line)) + body_stream << line << "\n"; + this->_body = body_stream.str(); + + ///* + std::cout << "-- start-line --" << std::endl; + std::cout << "method: " << this->_method << std::endl; + std::cout << "target: " << this->_target << std::endl; + std::cout << "protocol: " << this->_protocol << std::endl; + std::cout << std::endl; + std::cout << "-- headers --" << std::endl; + for (std::map::const_iterator it = this->_headers.begin(); it != this->_headers.end(); ++it) + std::cout << it->first << ": " << it->second << std::endl; + std::cout << std::endl; + std::cout << "-- body --" << std::endl << this->_body << std::endl; + //*/ +} + +http::Response http::Post::execute(void) +{ + http::Response response; + + // uh idk anymore + + return (response); +} + +// ------------------------------------------------------------------ diff --git a/src/requests_handling/HttpResponse.cpp b/src/requests_handling/HttpResponse.cpp index 5857f28..a5dbb24 100644 --- a/src/requests_handling/HttpResponse.cpp +++ b/src/requests_handling/HttpResponse.cpp @@ -6,17 +6,20 @@ /* By: mmoussou /* - do a map of all the status_text and get it from here, not storing them - get error pages from an array of predefined response, that would be modified by the config */ +// tmp, need to be cleaned +#include + using namespace webserv; http::Response::Response(void) @@ -36,6 +39,7 @@ std::string http::Response::str(void) const response << "\r\n"; response << this->_body; + std::cout << "------------ RESPONSE -------------" << std::endl << response.str(); return (response.str()); }