extend validation logic

This commit is contained in:
Quinten 2025-10-27 09:25:26 +01:00
parent d8a89c3814
commit 9358370044
4 changed files with 42 additions and 18 deletions

View File

@ -1,3 +1,5 @@
#include "webserv/http/RequestValidator.hpp"
#include <webserv/client/Client.hpp> #include <webserv/client/Client.hpp>
#include <webserv/handler/CgiHandler.hpp> // for CgiHandler #include <webserv/handler/CgiHandler.hpp> // for CgiHandler
#include <webserv/handler/ErrorHandler.hpp> // for ErrorHandler #include <webserv/handler/ErrorHandler.hpp> // for ErrorHandler
@ -93,15 +95,22 @@ void Client::request()
try try
{ {
// Thoughts: if a handler isn't returned, this could because of the error handler already setting up the response // Thoughts: if a handler isn't returned, this could because of the error handler already setting up the
// so, maybe we don't need to throw a 500 when no handler. Because that would override the actual error response. // response so, maybe we don't need to throw a 500 when no handler. Because that would override the actual
// How about the router, or a handler, throws an exception if something goes wrong, and we catch it here to make a 500 response? // error response. How about the router, or a handler, throws an exception if something goes wrong, and we
// catch it here to make a 500 response?
handler_ = router_->handleRequest(); handler_ = router_->handleRequest();
if (handler_ != nullptr) if (handler_ != nullptr)
{ {
handler_->handle(); handler_->handle();
} }
} }
catch (const RequestValidator::ValidationException &e)
{
Log::error("Exception during request handling: " + std::string(e.what()));
ErrorHandler::createErrorResponse(e.code(), *httpResponse_);
return;
}
catch (const std::exception &e) catch (const std::exception &e)
{ {
Log::error("Exception during request handling: " + std::string(e.what())); Log::error("Exception during request handling: " + std::string(e.what()));

View File

@ -65,3 +65,15 @@ std::optional<RequestValidator::ValidationError> RequestValidator::validateMetho
} }
return ValidationError{405, "Method Not Allowed"}; return ValidationError{405, "Method Not Allowed"};
} }
RequestValidator::ValidationException::ValidationException(int code) : code_(code){};
int RequestValidator::ValidationException::code() const noexcept
{
return code_;
}
const char *RequestValidator::ValidationException::what() const noexcept
{
return "Request validation failed";
}

View File

@ -1,9 +1,11 @@
#pragma once #pragma once
#include "webserv/config/AConfig.hpp" #include "webserv/config/AConfig.hpp"
#include <webserv/config/ServerConfig.hpp> #include <webserv/config/ServerConfig.hpp>
#include <webserv/http/HttpRequest.hpp> #include <webserv/http/HttpRequest.hpp>
#include <exception>
#include <optional> #include <optional>
#include <string> #include <string>
@ -15,6 +17,18 @@ class RequestValidator
int statusCode; int statusCode;
std::string message; std::string message;
}; };
class ValidationException : public std::exception
{
public:
ValidationException(int code);
[[nodiscard]] const char *what() const noexcept override;
[[nodiscard]] int code() const noexcept;
private:
int code_;
};
RequestValidator(const AConfig *config, const HttpRequest *request); RequestValidator(const AConfig *config, const HttpRequest *request);
[[nodiscard]] std::optional<ValidationError> validate() const; [[nodiscard]] std::optional<ValidationError> validate() const;
@ -25,4 +39,4 @@ class RequestValidator
[[nodiscard]] std::optional<ValidationError> validateContentLength() const; [[nodiscard]] std::optional<ValidationError> validateContentLength() const;
[[nodiscard]] std::optional<ValidationError> validateMethod() const; [[nodiscard]] std::optional<ValidationError> validateMethod() const;
}; };

View File

@ -1,4 +1,5 @@
#include "webserv/handler/ErrorHandler.hpp" #include "webserv/handler/ErrorHandler.hpp"
#include "webserv/http/RequestValidator.hpp"
#include <webserv/client/Client.hpp> // for Client #include <webserv/client/Client.hpp> // for Client
#include <webserv/config/AConfig.hpp> // for AConfig #include <webserv/config/AConfig.hpp> // for AConfig
@ -50,26 +51,15 @@ std::unique_ptr<AHandler> Router::handleRequest()
return nullptr; return nullptr;
} }
HttpResponse &response = client_->getHttpResponse(); HttpResponse &response = client_->getHttpResponse();
// const std::string &target = request.getTarget();
// static_cast<void>(target); // Suppress unused variable warning
// const std::string &method = request.getMethod();
const AConfig *config = request.getUri().getConfig(); const AConfig *config = request.getUri().getConfig();
auto validator = std::make_unique<RequestValidator>(config, &request); auto validator = std::make_unique<RequestValidator>(config, &request);
auto error = validator->validate(); auto error = validator->validate();
if (error.has_value()) if (error.has_value())
{ {
Log::warning("Request validation failed: " + error->message); Log::warning("Request validation failed: " + error->message);
ErrorHandler::createErrorResponse(error->statusCode, response, config); throw RequestValidator::ValidationException{error->statusCode};
return nullptr;
} }
// if (!isMethodSupported(method, *config))
// {
// return nullptr;
// // return ErrorHandler::getErrorResponse(405, config);
// }
if (request.getUri().isCgi()) if (request.getUri().isCgi())
{ {
try try
@ -80,7 +70,6 @@ std::unique_ptr<AHandler> Router::handleRequest()
catch (const std::exception &e) catch (const std::exception &e)
{ {
Log::error("CGI process failed: " + std::string(e.what())); Log::error("CGI process failed: " + std::string(e.what()));
// return ErrorHandler::getErrorResponse(500, config);
} }
} }
else else