From f0cd0af617ad673ce8c5edcbe198b20b514562df Mon Sep 17 00:00:00 2001 From: nicolas-arnaud Date: Sat, 12 Nov 2022 13:42:40 +0100 Subject: [PATCH] save 22-11-12-1 --- includes/Client.hpp | 6 ++- includes/Route.hpp | 2 +- srcs/load/Route.cpp | 4 +- srcs/sock/Client.cpp | 87 +++++++++++++++++++++++++++++++------------- srcs/sock/Master.cpp | 7 ++-- 5 files changed, 73 insertions(+), 33 deletions(-) diff --git a/includes/Client.hpp b/includes/Client.hpp index 59c00ab..f4d62e7 100644 --- a/includes/Client.hpp +++ b/includes/Client.hpp @@ -27,9 +27,13 @@ class Client { bool parseHeader(Env *env); string header_pick(string key, size_t id); void answer(); - bool check_method(string method); + bool check_method(); void send_cgi(string cgi, string path); void send_error(int error_code); void send_answer(string msg); + + bool getHeader(Env *env, string paquet); + bool getBody(string paquet); + friend class Master; }; diff --git a/includes/Route.hpp b/includes/Route.hpp index f2699f3..d5cbe20 100644 --- a/includes/Route.hpp +++ b/includes/Route.hpp @@ -11,7 +11,7 @@ class Route { public: std::vector< string > _indexs; - std::vector< string > _headers; + std::vector< string > _allowed_methods; std::map< string, string > _cgi; int _client_max_body_size; diff --git a/srcs/load/Route.cpp b/srcs/load/Route.cpp index 3679f2b..8012c44 100644 --- a/srcs/load/Route.cpp +++ b/srcs/load/Route.cpp @@ -26,11 +26,11 @@ Route::Route(Server *server, string location, JSONNode *datas) _indexs.push_back((*it)->str()); } } - if ((tmp = object["add_header"])) { + if ((tmp = object["allowed_methods"])) { JSONList headers = tmp->lst(); for (JSONList::iterator it = headers.begin(); it < headers.end(); it++) { - _headers.push_back((*it)->str()); + _allowed_methods.push_back((*it)->str()); } } if ((tmp = object["cgi"])) { diff --git a/srcs/sock/Client.cpp b/srcs/sock/Client.cpp index 765627b..116d062 100644 --- a/srcs/sock/Client.cpp +++ b/srcs/sock/Client.cpp @@ -25,39 +25,80 @@ void Client::clean(void) { _request.clear(); } +bool Client::getHeader(Env *env, string paquet) { + if (header_pick("Method:", 0) != "") + return true; + std::vector< string > lines = split(paquet, "\r\n"); + for (std::vector< string >::iterator it = lines.begin(); it < lines.end(); + it++) { + if (*it == "") { + if (!this->parseHeader(env)) + return false; + size_t pos = paquet.find("\r\n\r\n"); + if (pos != string::npos) + paquet.erase(pos + 4); + return true; + } else + _header += *it + "\r\n"; + } + _header.resize(_header.length() - 2); + return false; +} + +bool Client::getBody(string paquet) { + std::vector< string > lines = split(paquet, "\r\n"); + + long chunk_len = header_pick("Transfer-Encoding:", 0) == "chunked" + ? std::strtol(lines.at(0).c_str(), 0, 16) + : -1; + + std::vector< string >::iterator it; + for (it = lines.begin(); it < lines.end(); it++) { + if (chunk_len == -1 || it != lines.begin()) + _content += *it + "\r\n"; + } + _content.resize(_content.length() - 2); + if ((header_pick("Method:", 0) == "GET" && *it == "") || + (chunk_len == 0 || + std::strtoul(header_pick("Content-Length:", 0).c_str(), 0, 10) <= + _content.length())) { + cout << "Request received\n"; + return true; + } + return false; +} + bool Client::getRequest(Env *env, string paquet) { - // cout << "|===|paquet|===>" << paquet << "|===||\n"; + cout << "|===|paquet|===>\n" << paquet << "|===||\n"; if (paquet.length() < 1) // HTTPS? return false; std::vector< string > lines = split(paquet, "\n"); - long chunk_len; - chunk_len = (_content.length() > 0 && - header_pick("Transfer-Encoding:", 0) == "chunked") - ? std::strtol(lines.at(0).c_str(), 0, 16) - : -1; - cout << "Chunk length: " << chunk_len << "\n"; + long chunk_len = (_content.length() > 0 && + header_pick("Transfer-Encoding:", 0) == "chunked") + ? std::strtol(lines.at(0).c_str(), 0, 16) + : -1; + cout << "Chunk length: " << chunk_len << "\r\n"; for (std::vector< string >::iterator it = lines.begin(); it < lines.end(); it++) { - if (*it == "\r" && _content.length() == 0) { + if (*it == "\r" && header_pick("Method:", 0) == "") { if (!this->parseHeader(env)) return false; - } - if (*it != "\r" && _content.length() == 0) + } else if (*it != "\r" && header_pick("Method:", 0) == "") _header += *it + "\n"; - else if (chunk_len == -1 || it != lines.begin()) + else if (*it != "\r" && (chunk_len == -1 || it != lines.begin())) _content += *it + "\n"; } cout << "Content: \n-|" << _content << "|-\n"; if (_content.length() > 0) { _content.resize(_content.length() - 1); - if (header_pick("Method:", 0) == "GET" || + if ((header_pick("Method:", 0) == "GET" && _content.find("\r\n\r\n")) || (chunk_len == 0 || std::strtoul(header_pick("Content-Length:", 0).c_str(), 0, 10) <= _content.length())) { cout << "Request received\n"; return true; } - } else + } else if (header_pick("Method:", 0) == "") _header.resize(_header.length() - 1); return false; } @@ -96,18 +137,14 @@ bool Client::parseHeader(Env *env) { return true; } -bool Client::check_method(string method) { +bool Client::check_method() { std::vector< string > allowed; - if (method != "GET" && method != "POST" && method != "DELETE") + if (_method != "GET" && _method != "POST" && _method != "DELETE") send_error(405); - else if ((allowed = _route->_headers).size() > 0 && - std::find(allowed.begin(), allowed.end(), method) == + else if ((allowed = _route->_allowed_methods).size() > 0 && + std::find(allowed.begin(), allowed.end(), _method) == allowed.end()) { send_error(405); - } else if ((allowed = _server->_headers).size() > 0 && - std::find(allowed.begin(), allowed.end(), method) == - allowed.end()) { - send_error(405); } else return (true); return (false); @@ -126,7 +163,7 @@ void Client::answer() { cout << "URI: " << _uri << "\n"; cout << "Host: " << _host << "\n"; string ret; - if (check_method(_method)) { + if (check_method()) { string path = _route->correctUri(_uri); string cgi = _route->_cgi.size() ? _route->_cgi[get_extension(path)] : ""; @@ -185,12 +222,12 @@ void Client::send_error(int error_code) { return send_answer( "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n"); case 405: - return send_answer( - "HTTP/1.1 405 Method Not Allowed\r\nContent-Length: 0\r\n\r\n"); + return send_answer("HTTP/1.1 405 Method Not Allowed\r\nConnection: " + "close\r\nContent-Length: 0\r\n\r\n"); case 413: return send_answer( "HTTP/1.1 413 Payload Too " - "Large\r\nConnection:close\r\nContent-Length: 0\r\n\r\n"); + "Large\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"); } } diff --git a/srcs/sock/Master.cpp b/srcs/sock/Master.cpp index e093567..413906c 100644 --- a/srcs/sock/Master.cpp +++ b/srcs/sock/Master.cpp @@ -94,10 +94,9 @@ void Master::refresh(Env *env) { (socklen_t *)&addrlen); delete (*it); _childs.erase(it); - } else { - if ((*it)->getRequest(env, buffer)) - (*it)->answer(); - } + //} else if ((*it)->getRequest(env, buffer)) + } else if ((*it)->getHeader(env, buffer) && (*it)->getBody(buffer)) + (*it)->answer(); } } }