feat: replace URIParser with URI class for improved URI handling

This commit is contained in:
Quinten 2025-10-09 18:02:21 +02:00
parent 0f9fa38d8b
commit 35d17d8fa9
5 changed files with 44 additions and 33 deletions

View File

@ -3,7 +3,7 @@
#include <webserv/handler/ErrorHandler.hpp> // for ErrorHandler
#include <webserv/handler/FileHandler.hpp>
#include <webserv/handler/MIMETypes.hpp> // for MIMETypes
#include <webserv/handler/URIParser.hpp> // for URIParser
#include <webserv/handler/URI.hpp> // for URI
#include <webserv/http/HttpConstants.hpp> // for NOT_FOUND, FORBIDDEN, OK
#include <webserv/http/HttpResponse.hpp> // for HttpResponse
#include <webserv/log/Log.hpp> // for Log, LOCATION
@ -14,7 +14,7 @@
#include <string> // for basic_string, string, operator+, char_traits
#include <vector> // for vector
FileHandler::FileHandler(const AConfig *config, const URIParser &uriParser) : config_(config), uriParser_(uriParser)
FileHandler::FileHandler(const AConfig *config, const URI &URI) : config_(config), uri_(URI)
{
Log::trace(LOCATION);
}
@ -67,7 +67,7 @@ std::unique_ptr<HttpResponse> FileHandler::handleDirectory(const std::string &di
std::unique_ptr<HttpResponse> FileHandler::getResponse() const
{
Log::trace(LOCATION);
std::string filepath = uriParser_.getFullPath();
std::string filepath = uri_.getFullPath();
ResourceType resourceType = getResourceType(filepath);
switch (resourceType)
@ -85,11 +85,11 @@ FileHandler::ResourceType FileHandler::getResourceType(const std::string &path)
static_cast<void>(path);
Log::trace(LOCATION);
if (uriParser_.isFile())
if (uri_.isFile())
{
return FILE;
}
if (uriParser_.isDirectory())
if (uri_.isDirectory())
{
if (config_->get<std::vector<std::string>>("index").has_value())
{

View File

@ -3,7 +3,7 @@
#include "webserv/config/AConfig.hpp"
#include <webserv/config/LocationConfig.hpp>
#include <webserv/handler/URIParser.hpp>
#include <webserv/handler/URI.hpp>
#include <webserv/http/HttpResponse.hpp> // for HttpResponse
#include <cstdint> // for uint8_t
@ -11,18 +11,18 @@
#include <string> // for string
class AConfig;
class URIParser;
class URI;
class FileHandler
{
public:
FileHandler(const AConfig *config, const URIParser &uriParser);
FileHandler(const AConfig *config, const URI &uri);
[[nodiscard]] std::unique_ptr<HttpResponse> getResponse() const;
private:
const AConfig *config_;
const URIParser &uriParser_;
const URI &uri_;
enum ResourceType : uint8_t
{

View File

@ -4,21 +4,26 @@
#include <webserv/config/LocationConfig.hpp> // for LocationConfig
#include <webserv/config/ServerConfig.hpp> // for ServerConfig
#include <webserv/handler/URIParser.hpp>
#include <webserv/handler/URI.hpp>
#include <optional> // for optional
#include <stddef.h> // for size_t
#include <sys/stat.h> // for stat, S_ISDIR, S_ISREG
URIParser::URIParser(const std::string &uri, const ServerConfig &serverConfig)
: uriTrimmed_(utils::trim(uri, "/")), config_(matchConfig(uriTrimmed_, serverConfig))
URI::URI(const HttpRequest &request, const ServerConfig &serverConfig)
: uriTrimmed_(utils::trim(request.getTarget(), "/")), config_(matchConfig(uriTrimmed_, serverConfig))
{
parseUri(uri);
parseUri(request.getTarget());
parseFullpath();
authority_ = request.getHeaders().getHost().value();
authority_ += (serverConfig.get<int>("listen") != 80) // NOFORMAT
? ":" + std::to_string(serverConfig.get<int>("listen").value())
: "";
}
const AConfig *URIParser::matchConfig(const std::string &uri, const ServerConfig &serverConfig)
const AConfig *URI::matchConfig(const std::string &uri, const ServerConfig &serverConfig)
{
const auto &locations = serverConfig.getLocationPaths();
const AConfig *bestMatch = &serverConfig;
@ -42,7 +47,7 @@ const AConfig *URIParser::matchConfig(const std::string &uri, const ServerConfig
return bestMatch;
}
void URIParser::parseUri(const std::string &uri)
void URI::parseUri(const std::string &uri)
{
if (config_->getType() == "server")
{
@ -71,7 +76,7 @@ void URIParser::parseUri(const std::string &uri)
}
}
void URIParser::parseFullpath()
void URI::parseFullpath()
{
auto uriSegments = utils::split(fullPath_, '/');
@ -99,57 +104,57 @@ void URIParser::parseFullpath()
fullPath_ = FileUtils::joinPath(dir_, baseName_);
}
const AConfig *URIParser::getConfig() const
const AConfig *URI::getConfig() const
{
return config_;
}
bool URIParser::isFile() const
bool URI::isFile() const
{
return !baseName_.empty();
}
bool URIParser::isDirectory() const
bool URI::isDirectory() const
{
return baseName_.empty();
}
bool URIParser::isValid() const
bool URI::isValid() const
{
return FileUtils::isValidPath(fullPath_);
}
const std::string &URIParser::getBaseName() const
const std::string &URI::getBaseName() const
{
return baseName_;
}
std::string URIParser::getExtension() const
std::string URI::getExtension() const
{
return FileUtils::getExtension(baseName_);
}
const std::string &URIParser::getFullPath() const
const std::string &URI::getFullPath() const
{
return fullPath_;
}
const std::string &URIParser::getDir() const
const std::string &URI::getDir() const
{
return dir_;
}
const std::string &URIParser::getPathInfo() const
const std::string &URI::getPathInfo() const
{
return pathInfo_;
}
const std::string &URIParser::getQuery() const
const std::string &URI::getQuery() const
{
return query_;
}
const std::string &URIParser::getFragment() const
const std::string &URI::getFragment() const
{
return fragment_;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "webserv/config/AConfig.hpp"
#include "webserv/http/HttpRequest.hpp"
#include <webserv/config/LocationConfig.hpp>
#include <webserv/config/ServerConfig.hpp>
@ -11,14 +12,15 @@
class LocationConfig;
class ServerConfig;
class URIParser
class URI
{
public:
URIParser(const std::string &uri, const ServerConfig &serverConfig);
URI(const HttpRequest &request, const ServerConfig &serverConfig);
[[nodiscard]] bool isFile() const;
[[nodiscard]] bool isDirectory() const;
[[nodiscard]] bool isValid() const;
[[nodiscard]] bool isCgi() const;
[[nodiscard]] std::string getExtension() const;
[[nodiscard]] const AConfig *getConfig() const;
@ -28,6 +30,8 @@ class URIParser
[[nodiscard]] const std::string &getPathInfo() const;
[[nodiscard]] const std::string &getQuery() const;
[[nodiscard]] const std::string &getFragment() const;
[[nodiscard]] const std::string &getAuthority() const;
[[nodiscard]] const std::string &getScheme() const;
private:
void parseUri(const std::string &uri);
@ -41,6 +45,8 @@ class URIParser
std::string pathInfo_;
std::string query_;
std::string fragment_;
std::string authority_;
std::string scheme_;
static const AConfig *matchConfig(const std::string &uri, const ServerConfig &serverConfig);
};

View File

@ -5,7 +5,7 @@
#include <webserv/config/directive/ADirective.hpp>
#include <webserv/handler/ErrorHandler.hpp> // for ErrorHandler
#include <webserv/handler/FileHandler.hpp> // for FileHandler
#include <webserv/handler/URIParser.hpp> // for URIParser
#include <webserv/handler/URI.hpp> // for URI
#include <webserv/http/HttpHeaders.hpp> // for HttpHeaders
#include <webserv/log/Log.hpp> // for LOCATION, Log
#include <webserv/router/Router.hpp>
@ -40,17 +40,17 @@ std::unique_ptr<HttpResponse> Router::handleRequest(const HttpRequest &request)
{
return ErrorHandler::getErrorResponse(400);
}
URIParser uriParser{request.getTarget(), *serverConfig};
URI uri{request, *serverConfig};
const std::string &target = request.getTarget();
static_cast<void>(target); // Suppress unused variable warning
const std::string &method = request.getMethod();
const AConfig *config = uriParser.getConfig();
const AConfig *config = uri.getConfig();
if (!isMethodSupported(method, *config))
{
return ErrorHandler::getErrorResponse(405, config);
}
FileHandler fileHandler(config, uriParser);
FileHandler fileHandler(config, uri);
return fileHandler.getResponse();
}