From 858c362a088746162d3b32f4af5ada2fddee82be Mon Sep 17 00:00:00 2001 From: lgreau <137093922+GREAULouen@users.noreply.github.com> Date: Fri, 17 Jan 2025 10:46:07 +0100 Subject: [PATCH 1/3] Fixed route printing --- src/Server/Route.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Server/Route.cpp b/src/Server/Route.cpp index c90af735..bc1cd972 100644 --- a/src/Server/Route.cpp +++ b/src/Server/Route.cpp @@ -6,7 +6,7 @@ /* By: lgreau +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/06 13:58:51 by lgreau #+# #+# */ -/* Updated: 2025/01/14 15:30:25 by lgreau ### ########.fr */ +/* Updated: 2025/01/17 09:33:21 by lgreau ### ########.fr */ /* */ /* ************************************************************************** */ @@ -95,10 +95,10 @@ std::ostream& operator<<(std::ostream& os, const Route& route) { os << std::left << std::setw(24) << " |- upload dir: " << route.getUploadDir() << "\n"; } - os << std::left << std::setw(32) << " |- client max body size: " << route.getClientMaxBodySize() << " bytes\n"; - os << std::left << std::setw(32) << " |- client body buffer size: " << route.getClientBodyBufferSize() + os << std::left << std::setw(32) << " |- client max body size: " << route.getClientMaxBodySize() << " bytes\n"; + os << std::left << std::setw(32) << " |- client body buffer size: " << route.getClientBodyBufferSize() << " bytes\n"; - os << std::left << std::setw(32) << " |- client header buffer size: " << route.getClientHeaderBufferSize() + os << std::left << std::setw(32) << " |- client header buffer size: " << route.getClientHeaderBufferSize() << " bytes\n"; if (!route.getCgiHandlers().empty()) { From 2d8c0c462dd425a99060633f8207e4592909134f Mon Sep 17 00:00:00 2001 From: lgreau <137093922+GREAULouen@users.noreply.github.com> Date: Fri, 17 Jan 2025 15:03:47 +0100 Subject: [PATCH 2/3] Fixed infinite loop on parsing --- config/bs.conf | 580 ++++++++++++++++++++++++ include/configuration/Parser.hpp | 3 +- include/configuration/ParsingErrors.hpp | 9 +- src/configuration/Lexer.cpp | 6 +- src/configuration/Parser.cpp | 35 +- 5 files changed, 607 insertions(+), 26 deletions(-) create mode 100644 config/bs.conf diff --git a/config/bs.conf b/config/bs.conf new file mode 100644 index 00000000..0833a0fb --- /dev/null +++ b/config/bs.conf @@ -0,0 +1,580 @@ +http { + server { + location / { + /* ************************************************************************** */ + /* */ + /* ::: :::::::: */ + /* Parser.cpp :+: :+: :+: */ + /* +:+ +:+ +:+ */ + /* By: lgreau +#+ +:+ +#+ */ + /* +#+#+#+#+#+ +#+ */ + /* Created: 2024/10/02 14:02:16 by lgreau #+# #+# */ + /* Updated: 2025/01/17 14:57:19 by lgreau ### ########.fr */ + /* */ + /* ************************************************************************** */ + } + + #include "Parser.hpp" + + #include + #include + #include + + #include "Logger.hpp" + + Parser::Parser(Lexer& lexer) : _lexer(lexer), _currentToken(lexer.nextToken()) {} + + void Parser::expect(eTokenType type) { + if (_currentToken.type != type) { + if (_currentToken.type == TOKEN_STRING) + reportError(UNEXPECTED_TOKEN, tokenToString.at(type), _currentToken.value); + else + reportError(UNEXPECTED_TOKEN, tokenToString.at(type), tokenToString.at(_currentToken.type)); + } + + _currentToken = _lexer.nextToken(); + } + + std::vector> Parser::splitServerConfigs(const std::vector& serverConfigs) { + std::unordered_map> groupedConfigs; + std::vector> result; + + for (const auto& config : serverConfigs) { + std::string key = config.getHostIP() + ":" + std::to_string(config.getPort()); + groupedConfigs[key].push_back(config); + } + + result.reserve(groupedConfigs.size()); + for (const auto& [fst, snd] : groupedConfigs) { + result.push_back(snd); + } + + return result; + } + + std::vector> Parser::parse() { + std::vector servers; + expect(TOKEN_HTTP); + expect(TOKEN_OPEN_BRACE); + if (!_parsingErrors.empty()) + throw std::runtime_error("Found some parsing errors"); + + try { + while ((_currentToken.type != TOKEN_CLOSE_BRACE && _currentToken.type != TOKEN_EOF) && !stopServer) + servers.push_back(parseServer()); + } catch (std::exception& e) { + throw std::runtime_error("Found some parsing errors"); + } + + expect(TOKEN_CLOSE_BRACE); + + if (!_parsingErrors.empty()) + throw std::runtime_error("Found some parsing errors"); + + return splitServerConfigs(servers); + } + + ServerConfig Parser::parseServer() { + expect(TOKEN_SERVER); + expect(TOKEN_OPEN_BRACE); + + ServerConfig server; + + while ((_currentToken.type != TOKEN_CLOSE_BRACE && _currentToken.type != TOKEN_EOF) && !stopServer) { + LOG_DEBUG(_currentToken.value); + switch (_currentToken.type) { + case TOKEN_LISTEN: { + expect(TOKEN_LISTEN); + if (_currentToken.type == TOKEN_IP_V4) { + server.setHost(_currentToken.value); + _currentToken = _lexer.nextToken(); // Consume IP + + if (_currentToken.type == TOKEN_STRING && _currentToken.value[0] == ':') { // In the form ":8080" + server.setPort(std::stoi(_currentToken.value.substr(1, _currentToken.value.size() - 1))); + _currentToken = _lexer.nextToken(); + } + } else if (_currentToken.type == TOKEN_NUMBER) { + server.setPort(std::stoi(_currentToken.value)); + _currentToken = _lexer.nextToken(); // Consume port + } else { + reportError(LISTEN_MISSING_VALUES, "listen [host|port] or listen [host]:[port]", "listen [ ]"); + } + + expect(TOKEN_SEMICOLON); + break; + } + + case TOKEN_SERVER_NAME: { + _currentToken = _lexer.nextTokenWhitespace(); + + std::stringstream ss(_currentToken.value); + std::vector server_names; + std::string tmp; + + while (std::getline(ss, tmp, ' ')) + if (tmp.size() > 0) { + std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); + server.addServerName(tmp); + } + + if (server.getServerNames().empty()) + reportError(SERVER_NAME_MISSING_VALUES, "name1 name2", ""); + + _currentToken = _lexer.nextToken(); + expect(TOKEN_SEMICOLON); + break; + } + + case TOKEN_ROOT: + expect(TOKEN_ROOT); + server.setRoot(_currentToken.value); + expect(TOKEN_STRING); + expect(TOKEN_SEMICOLON); + break; + + case TOKEN_INDEX: + expect(TOKEN_INDEX); + server.setIndex(_currentToken.value); + expect(TOKEN_STRING); + expect(TOKEN_SEMICOLON); + break; + + case TOKEN_CLIENT_MAX_BODY_SIZE: { + expect(TOKEN_CLIENT_MAX_BODY_SIZE); + size_t maxBodySize = 0; + size_t mbValue = std::stoul(_currentToken.value); + expect(TOKEN_NUMBER); + while (_currentToken.type == TOKEN_STRING) { + switch (_currentToken.value[0]) { + case 'k': + case 'K': + mbValue *= 1024; + break; + case 'm': + case 'M': + mbValue *= 1024 * 1024; + break; + case 'g': + case 'G': + mbValue *= 1024 * 1024 * 1024; + break; + case 'b': + case 'B': + break; + default: + reportError(INVALID_UNIT, "'b', 'k', 'm' or 'g'", _currentToken.value); + } + _currentToken = _lexer.nextToken(); // Moves past the suffix + + if (_currentToken.type != TOKEN_NUMBER) + break; + maxBodySize += mbValue; + mbValue = std::stoul(_currentToken.value); + + _currentToken = _lexer.nextToken(); // Move past the number + } + maxBodySize += mbValue; + server.setClientMaxBodySize(maxBodySize); + expect(TOKEN_SEMICOLON); + break; + } + + case TOKEN_CLIENT_BODY_BUFFER_SIZE: { + expect(TOKEN_CLIENT_BODY_BUFFER_SIZE); + size_t bodyBufferSize = 0; + size_t mbValue = std::stoul(_currentToken.value); + expect(TOKEN_NUMBER); + while (_currentToken.type == TOKEN_STRING) { + switch (_currentToken.value[0]) { + case 'k': + case 'K': + mbValue *= 1024; + break; + case 'm': + case 'M': + mbValue *= 1024 * 1024; + break; + case 'g': + case 'G': + mbValue *= 1024 * 1024 * 1024; + break; + case 'b': + case 'B': + break; + default: + reportError(INVALID_UNIT, "'b', 'k', 'm' or 'g'", _currentToken.value); + } + _currentToken = _lexer.nextToken(); // Moves past the suffix + + if (_currentToken.type != TOKEN_NUMBER) + break; + bodyBufferSize += mbValue; + mbValue = std::stoul(_currentToken.value); + + _currentToken = _lexer.nextToken(); // Move past the number + } + bodyBufferSize += mbValue; + server.setClientBodyBufferSize(bodyBufferSize); + expect(TOKEN_SEMICOLON); + break; + } + + case TOKEN_CLIENT_HEADER_BUFFER_SIZE: { + expect(TOKEN_CLIENT_HEADER_BUFFER_SIZE); + size_t headerBufferSize = 0; + size_t mbValue = std::stoul(_currentToken.value); + expect(TOKEN_NUMBER); + while (_currentToken.type == TOKEN_STRING) { + switch (_currentToken.value[0]) { + case 'k': + case 'K': + mbValue *= 1024; + break; + case 'm': + case 'M': + mbValue *= 1024 * 1024; + break; + case 'g': + case 'G': + mbValue *= 1024 * 1024 * 1024; + break; + case 'b': + case 'B': + break; + default: + reportError(INVALID_UNIT, "'b', 'k', 'm' or 'g'", _currentToken.value); + } + _currentToken = _lexer.nextToken(); // Moves past the suffix + + if (_currentToken.type != TOKEN_NUMBER) + break; + headerBufferSize += mbValue; + mbValue = std::stoul(_currentToken.value); + + _currentToken = _lexer.nextToken(); // Move past the number + } + headerBufferSize += mbValue; + server.setClientHeaderBufferSize(headerBufferSize); + expect(TOKEN_SEMICOLON); + break; + } + + case TOKEN_UPLOAD_DIR: + expect(TOKEN_UPLOAD_DIR); + server.setUploadDir(_currentToken.value); + expect(TOKEN_STRING); + expect(TOKEN_SEMICOLON); + break; + + case TOKEN_REQUEST_TIMEOUT: { + expect(TOKEN_REQUEST_TIMEOUT); + size_t timeout = 0; + size_t msValue = 1000 * std::stoul(_currentToken.value); // By default, read in seconds + expect(TOKEN_NUMBER); + while (_currentToken.type == TOKEN_STRING) { + if (_currentToken.value == "ms") // 1/1000th of a second + msValue /= 1000; + else if (_currentToken.value == "m") // 60 seconds + msValue *= 60; + else if (_currentToken.value == "h") // 60 minutes + msValue *= 60 * 60; + else if (_currentToken.value == "d") // 24 hours + msValue *= 24 * 60 * 60; + else if (_currentToken.value == "w") // 7 days + msValue *= 7 * 24 * 60 * 60; + else if (_currentToken.value == "M") // 30 days + msValue *= 30 * 24 * 60 * 60; + else if (_currentToken.value == "y") // 365 days + msValue *= 365 * 24 * 60 * 60; + + _currentToken = _lexer.nextToken(); // Moves past the suffix + + if (_currentToken.type != TOKEN_NUMBER) + break; + timeout += msValue; + msValue = 1000 * std::stoul(_currentToken.value); + + _currentToken = _lexer.nextToken(); // Move past the number + } + timeout += msValue; + server.setRequestTimeout(timeout); + expect(TOKEN_SEMICOLON); + break; + } + + case TOKEN_ERROR_PAGE: { + expect(TOKEN_ERROR_PAGE); + int code = std::stoi(_currentToken.value); + expect(TOKEN_NUMBER); + std::string path = _currentToken.value; + expect(TOKEN_STRING); + auto errorPages = server.getErrorPages(); + errorPages[code] = path; + server.setErrorPages(errorPages); + expect(TOKEN_SEMICOLON); + break; + } + + case TOKEN_LOCATION: { + std::vector routes = server.getRoutes(); + routes.push_back(parseRoute()); + server.setRoutes(routes); + break; + } + + default: + reportError(UNEXPECTED_TOKEN, "something", _currentToken.value); + throw std::runtime_error("Found some parsing errors"); + } + } + + expect(TOKEN_CLOSE_BRACE); + return server; + } + + Route Parser::parseRoute() { + expect(TOKEN_LOCATION); + Route route; + route.setPath(_currentToken.value); + expect(TOKEN_STRING); + expect(TOKEN_OPEN_BRACE); + + while ((_currentToken.type != TOKEN_CLOSE_BRACE && _currentToken.type != TOKEN_EOF) && !stopServer) { + LOG_DEBUG(_currentToken.value); + switch (_currentToken.type) { + case TOKEN_ALLOW_METHODS: + expect(TOKEN_ALLOW_METHODS); + { + std::vector methods; + while (_currentToken.type == TOKEN_STRING) { + methods.push_back(_currentToken.value); + _currentToken = _lexer.nextToken(); + } + if (methods.size() <= 0) + reportError(ALLOW_METHODS_MISSING_VALUES, "at least one method: 'GET', 'POST' or 'DELETE'", + "None"); + route.setMethods(methods); + } + expect(TOKEN_SEMICOLON); + break; + + case TOKEN_ALIAS: + expect(TOKEN_ALIAS); + route.setAlias(_currentToken.value); + expect(TOKEN_STRING); + expect(TOKEN_SEMICOLON); + break; + + case TOKEN_AUTOINDEX: + expect(TOKEN_AUTOINDEX); + if (_currentToken.type == TOKEN_ON) { + route.setAutoindex(true); + } else if (_currentToken.type == TOKEN_OFF) { + route.setAutoindex(false); + } else { + reportError(AUTOINDEX_BAD_VALUE, "'on' or 'off'", _currentToken.value); + } + _currentToken = _lexer.nextToken(); + expect(TOKEN_SEMICOLON); + break; + + case TOKEN_CGI: { + expect(TOKEN_CGI); + std::string ext = _currentToken.value; + if (ext[0] != '.' || ext.size() <= 1) + reportError(CGI_BAD_EXTENSION, ".__ e.g: '.py' or '.php'", ext); + + expect(TOKEN_STRING); + std::string handler = _currentToken.value; + if (handler[handler.size() - 1] == '/') + reportError(CGI_BAD_EXECUTABLE, "CGI executable for " + ext + " must be a file", handler); + + expect(TOKEN_STRING); + auto cgiHandlers = route.getCgiHandlers(); + if (cgiHandlers.find(ext) == cgiHandlers.end()) + cgiHandlers[ext] = handler; + route.setCgiHandlers(cgiHandlers); + expect(TOKEN_SEMICOLON); + break; + } + + case TOKEN_ROOT: + expect(TOKEN_ROOT); + route.setRoot(_currentToken.value); + expect(TOKEN_STRING); + expect(TOKEN_SEMICOLON); + break; + + case TOKEN_INDEX: + expect(TOKEN_INDEX); + route.setIndex(_currentToken.value); + expect(TOKEN_STRING); + expect(TOKEN_SEMICOLON); + break; + + case TOKEN_UPLOAD_DIR: + expect(TOKEN_UPLOAD_DIR); + route.setUploadDir(_currentToken.value); + expect(TOKEN_STRING); + expect(TOKEN_SEMICOLON); + break; + + case TOKEN_RETURN: { + expect(TOKEN_RETURN); + + if (_currentToken.type == TOKEN_NUMBER) + route.setCode(std::stoi(_currentToken.value)); + else + route.setCode(302); + + _currentToken = _lexer.nextTokenWhitespace(); + if (_currentToken.type == TOKEN_STRING) { + route.setRedirect(_currentToken.value.substr(1, _currentToken.value.size() - 1)); + _currentToken = _lexer.nextToken(); + expect(TOKEN_SEMICOLON); + } else if (_currentToken.type == TOKEN_SEMICOLON) { + _currentToken = _lexer.nextToken(); + break; + } else { + throw std::runtime_error("Unexpected token"); + } + + break; + } + + case TOKEN_CLIENT_MAX_BODY_SIZE: { + expect(TOKEN_CLIENT_MAX_BODY_SIZE); + size_t maxBodySize = 0; + size_t mbValue = std::stoul(_currentToken.value); + expect(TOKEN_NUMBER); + while (_currentToken.type == TOKEN_STRING) { + switch (_currentToken.value[0]) { + case 'k': + case 'K': + mbValue *= 1024; + break; + case 'm': + case 'M': + mbValue *= 1024 * 1024; + break; + case 'g': + case 'G': + mbValue *= 1024 * 1024 * 1024; + break; + } + _currentToken = _lexer.nextToken(); // Moves past the suffix + + if (_currentToken.type != TOKEN_NUMBER) + break; + maxBodySize += mbValue; + mbValue = std::stoul(_currentToken.value); + + _currentToken = _lexer.nextToken(); // Move past the number + } + maxBodySize += mbValue; + route.setClientMaxBodySize(maxBodySize); + expect(TOKEN_SEMICOLON); + break; + } + + case TOKEN_CLIENT_BODY_BUFFER_SIZE: { + expect(TOKEN_CLIENT_BODY_BUFFER_SIZE); + size_t bodyBufferSize = 0; + size_t mbValue = std::stoul(_currentToken.value); + expect(TOKEN_NUMBER); + while (_currentToken.type == TOKEN_STRING) { + switch (_currentToken.value[0]) { + case 'k': + case 'K': + mbValue *= 1024; + break; + case 'm': + case 'M': + mbValue *= 1024 * 1024; + break; + case 'g': + case 'G': + mbValue *= 1024 * 1024 * 1024; + break; + } + _currentToken = _lexer.nextToken(); // Moves past the suffix + + if (_currentToken.type != TOKEN_NUMBER) + break; + bodyBufferSize += mbValue; + mbValue = std::stoul(_currentToken.value); + + _currentToken = _lexer.nextToken(); // Move past the number + } + bodyBufferSize += mbValue; + route.setClientBodyBufferSize(bodyBufferSize); + expect(TOKEN_SEMICOLON); + break; + } + + case TOKEN_CLIENT_HEADER_BUFFER_SIZE: { + expect(TOKEN_CLIENT_HEADER_BUFFER_SIZE); + size_t headerBufferSize = 0; + size_t mbValue = std::stoul(_currentToken.value); + expect(TOKEN_NUMBER); + while (_currentToken.type == TOKEN_STRING) { + switch (_currentToken.value[0]) { + case 'k': + case 'K': + mbValue *= 1024; + break; + case 'm': + case 'M': + mbValue *= 1024 * 1024; + break; + case 'g': + case 'G': + mbValue *= 1024 * 1024 * 1024; + break; + } + _currentToken = _lexer.nextToken(); // Moves past the suffix + + if (_currentToken.type != TOKEN_NUMBER) + break; + headerBufferSize += mbValue; + mbValue = std::stoul(_currentToken.value); + + _currentToken = _lexer.nextToken(); // Move past the number + } + headerBufferSize += mbValue; + route.setClientHeaderBufferSize(headerBufferSize); + expect(TOKEN_SEMICOLON); + break; + } + + default: + reportError(UNEXPECTED_TOKEN, "something", _currentToken.value); + throw std::runtime_error("Found some parsing errors"); + } + } + + expect(TOKEN_CLOSE_BRACE); + return route; + } + + void Parser::reportError(eParsingErrors error, std::string expected, std::string found) { + std::ostringstream errorMsg; + + errorMsg << COLOR(BLUE, _lexer.getErrorPrefix()) << COLOR(RED, parsingErrorsMessages.at(error).at(ERROR_NAME)) + << std::endl + << std::endl + << std::left << std::setw(12) << parsingErrorsMessages.at(error).at(ERROR_TEXT); + + errorMsg << expected; + + errorMsg << std::endl << std::left << std::setw(12) << "got: " << found << std::endl; + + _parsingErrors.push_back(errorMsg.str()); + } + + void Parser::flushErrors() const { + for (const auto& msg : _parsingErrors) std::cerr << msg << std::endl << std::endl; + } + + } +} \ No newline at end of file diff --git a/include/configuration/Parser.hpp b/include/configuration/Parser.hpp index bbec128f..4a619c16 100644 --- a/include/configuration/Parser.hpp +++ b/include/configuration/Parser.hpp @@ -6,7 +6,7 @@ /* By: lgreau +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/02 13:58:34 by lgreau #+# #+# */ -/* Updated: 2025/01/16 10:33:40 by lgreau ### ########.fr */ +/* Updated: 2025/01/17 14:36:03 by lgreau ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,6 +21,7 @@ #include "ParsingErrors.hpp" #include "Route.hpp" #include "ServerConfig.hpp" +#include "globals.hpp" #define REGEX_PORT "[0-9]{1,5}" diff --git a/include/configuration/ParsingErrors.hpp b/include/configuration/ParsingErrors.hpp index 9d9664cb..e933e76f 100644 --- a/include/configuration/ParsingErrors.hpp +++ b/include/configuration/ParsingErrors.hpp @@ -6,7 +6,7 @@ /* By: lgreau +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/07 17:08:16 by lgreau #+# #+# */ -/* Updated: 2025/01/16 11:53:34 by lgreau ### ########.fr */ +/* Updated: 2025/01/17 15:01:40 by lgreau ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,6 +35,13 @@ enum eParsingErrors { #define ERROR_NAME 0 #define ERROR_TEXT 1 +#define POSSIBLE_SERVER_CONFIGS \ + "'location', 'listen', 'server_name', 'root', 'index', 'client_max_body_size', 'client_body_buffer_size', " \ + "'client_header_buffer_size', 'uplaod_dir', 'request_timeout' or 'error_page'" +#define POSSIBLE_ROUTE_CONFIGS \ + "'root', 'index', 'client_max_body_size', 'client_body_buffer_size', 'client_header_buffer_size', 'uplaod_dir', " \ + "'allow_methods', 'autoindex', 'alias', 'cgi' or 'return'" + const std::map > parsingErrorsMessages = { {UNEXPECTED_TOKEN, {"UNEXPECTED_TOKEN", "expected: "}}, {INVALID_UNIT, {"INVALID_UNIT", "expected: "}}, diff --git a/src/configuration/Lexer.cpp b/src/configuration/Lexer.cpp index 63c49805..6a583be9 100644 --- a/src/configuration/Lexer.cpp +++ b/src/configuration/Lexer.cpp @@ -6,7 +6,7 @@ /* By: lgreau +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/02 13:33:07 by lgreau #+# #+# */ -/* Updated: 2025/01/16 10:26:15 by lgreau ### ########.fr */ +/* Updated: 2025/01/17 14:58:21 by lgreau ### ########.fr */ /* */ /* ************************************************************************** */ @@ -153,10 +153,6 @@ Token Lexer::parseKeywordOrString() { return {fst, value, _line, _column}; } - // LOG_INFO("unmatched token string: " + value); - // if (value.find_first_not_of("0123456789") == std::string::npos) - // return {TOKEN_NUMBER, value, _line, _column}; - return {TOKEN_STRING, value, _line, _column}; // Default to string if not a keyword } diff --git a/src/configuration/Parser.cpp b/src/configuration/Parser.cpp index 67a7e1ae..09fe7bf0 100644 --- a/src/configuration/Parser.cpp +++ b/src/configuration/Parser.cpp @@ -6,7 +6,7 @@ /* By: lgreau +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/02 14:02:16 by lgreau #+# #+# */ -/* Updated: 2025/01/16 17:59:38 by lgreau ### ########.fr */ +/* Updated: 2025/01/17 15:02:06 by lgreau ### ########.fr */ /* */ /* ************************************************************************** */ @@ -52,8 +52,15 @@ std::vector> Parser::parse() { std::vector servers; expect(TOKEN_HTTP); expect(TOKEN_OPEN_BRACE); + if (!_parsingErrors.empty()) + throw std::runtime_error("Found some parsing errors"); - while (_currentToken.type != TOKEN_CLOSE_BRACE) servers.push_back(parseServer()); + try { + while ((_currentToken.type != TOKEN_CLOSE_BRACE && _currentToken.type != TOKEN_EOF) && !stopServer) + servers.push_back(parseServer()); + } catch (std::exception& e) { + throw std::runtime_error("Found some parsing errors"); + } expect(TOKEN_CLOSE_BRACE); @@ -69,7 +76,7 @@ ServerConfig Parser::parseServer() { ServerConfig server; - while (_currentToken.type != TOKEN_CLOSE_BRACE) { + while ((_currentToken.type != TOKEN_CLOSE_BRACE && _currentToken.type != TOKEN_EOF) && !stopServer) { switch (_currentToken.type) { case TOKEN_LISTEN: { expect(TOKEN_LISTEN); @@ -311,9 +318,8 @@ ServerConfig Parser::parseServer() { } default: - reportError(UNEXPECTED_TOKEN, "something", _currentToken.value); - _currentToken = _lexer.nextToken(); - break; + reportError(UNEXPECTED_TOKEN, POSSIBLE_SERVER_CONFIGS, _currentToken.value); + throw std::runtime_error("Found some parsing errors"); } } @@ -328,7 +334,7 @@ Route Parser::parseRoute() { expect(TOKEN_STRING); expect(TOKEN_OPEN_BRACE); - while (_currentToken.type != TOKEN_CLOSE_BRACE) { + while ((_currentToken.type != TOKEN_CLOSE_BRACE && _currentToken.type != TOKEN_EOF) && !stopServer) { switch (_currentToken.type) { case TOKEN_ALLOW_METHODS: expect(TOKEN_ALLOW_METHODS); @@ -536,9 +542,8 @@ Route Parser::parseRoute() { } default: - reportError(UNEXPECTED_TOKEN, "something", _currentToken.value); - _currentToken = _lexer.nextToken(); - break; + reportError(UNEXPECTED_TOKEN, POSSIBLE_ROUTE_CONFIGS, _currentToken.value); + throw std::runtime_error("Found some parsing errors"); } } @@ -554,15 +559,7 @@ void Parser::reportError(eParsingErrors error, std::string expected, std::string << std::endl << std::left << std::setw(12) << parsingErrorsMessages.at(error).at(ERROR_TEXT); - switch (error) { - case UNEXPECTED_TOKEN: - errorMsg << "'" << expected << "'"; - break; - - default: - errorMsg << expected; - break; - } + errorMsg << expected; errorMsg << std::endl << std::left << std::setw(12) << "got: " << found << std::endl; From ad44e4bb5d3a82e05d997356c9fce8bdb3cc8760 Mon Sep 17 00:00:00 2001 From: lgreau <137093922+GREAULouen@users.noreply.github.com> Date: Fri, 17 Jan 2025 15:16:13 +0100 Subject: [PATCH 3/3] Clamping client_header_buffer_size to MAX_HEADER_BUFFER_SIZE --- include/configuration/Parser.hpp | 3 ++- include/configuration/ParsingErrors.hpp | 2 +- src/configuration/Parser.cpp | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/configuration/Parser.hpp b/include/configuration/Parser.hpp index 4a619c16..08bce9fd 100644 --- a/include/configuration/Parser.hpp +++ b/include/configuration/Parser.hpp @@ -6,7 +6,7 @@ /* By: lgreau +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/02 13:58:34 by lgreau #+# #+# */ -/* Updated: 2025/01/17 14:36:03 by lgreau ### ########.fr */ +/* Updated: 2025/01/17 15:14:24 by lgreau ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,6 +24,7 @@ #include "globals.hpp" #define REGEX_PORT "[0-9]{1,5}" +#define MAX_HEADER_BUFFER_SIZE 1024 class Parser { private: diff --git a/include/configuration/ParsingErrors.hpp b/include/configuration/ParsingErrors.hpp index e933e76f..32c8547e 100644 --- a/include/configuration/ParsingErrors.hpp +++ b/include/configuration/ParsingErrors.hpp @@ -6,7 +6,7 @@ /* By: lgreau +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/07 17:08:16 by lgreau #+# #+# */ -/* Updated: 2025/01/17 15:01:40 by lgreau ### ########.fr */ +/* Updated: 2025/01/17 15:11:45 by lgreau ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/configuration/Parser.cpp b/src/configuration/Parser.cpp index 09fe7bf0..09a2f039 100644 --- a/src/configuration/Parser.cpp +++ b/src/configuration/Parser.cpp @@ -6,7 +6,7 @@ /* By: lgreau +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/02 14:02:16 by lgreau #+# #+# */ -/* Updated: 2025/01/17 15:02:06 by lgreau ### ########.fr */ +/* Updated: 2025/01/17 15:14:39 by lgreau ### ########.fr */ /* */ /* ************************************************************************** */ @@ -250,6 +250,10 @@ ServerConfig Parser::parseServer() { } headerBufferSize += mbValue; server.setClientHeaderBufferSize(headerBufferSize); + if (headerBufferSize > MAX_HEADER_BUFFER_SIZE) { + LOG_WARN("client_header_buffer_size set higher than MAX_HEADER_BUFFER_SIZE: 1024"); + server.setClientHeaderBufferSize(headerBufferSize); + } expect(TOKEN_SEMICOLON); break; }