webserv/webserv/handler/URIParser.cpp
2025-10-06 15:16:53 +02:00

98 lines
2.6 KiB
C++

#include <webserv/handler/URIParser.hpp>
#include <webserv/config/LocationConfig.hpp> // for LocationConfig
#include <webserv/config/ServerConfig.hpp> // for ServerConfig
#include <optional> // for optional
#include <vector> // for vector
#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) : _locationConfig(nullptr)
{
const auto &locations = serverConfig.getLocationPaths();
size_t maxMatchLength = 0;
for (const auto &locationPath : locations)
{
if (uri.starts_with((locationPath == "/") ? locationPath : locationPath + "/"))
{ // TODO HMHMMz why does it need to end on a /?
if (locationPath.length() > maxMatchLength)
{
maxMatchLength = locationPath.length();
_locationConfig = serverConfig.getLocation(locationPath);
}
}
}
root_ = _locationConfig != nullptr ? _locationConfig->get<std::string>("root").value_or("") : "";
if (!root_.empty() && root_.back() == '/')
{
root_.pop_back(); // Remove trailing slash to avoid double slashes in path
}
relativePath_ = uri.substr(maxMatchLength);
if (relativePath_.empty() || relativePath_[0] != '/')
{
relativePath_ = "/" + relativePath_;
}
}
std::string URIParser::getFilePath() const
{
return root_ + relativePath_;
}
std::string URIParser::getFilename() const
{
size_t lastSlash = relativePath_.find_last_of('/');
if (lastSlash == std::string::npos)
{
return relativePath_; // No slashes, return the whole path
}
return relativePath_.substr(lastSlash + 1);
}
std::string URIParser::getExtension() const
{
std::string filename = getFilename();
size_t lastDot = filename.find_last_of('.');
if (lastDot == std::string::npos || lastDot == 0 || lastDot == filename.length() - 1)
{
return ""; // No extension found or dot is at start/end
}
return filename.substr(lastDot + 1);
}
LocationConfig const *URIParser::getLocation() const
{
return _locationConfig;
}
bool URIParser::isFile() const
{
struct stat pathStat{};
if (stat(getFilePath().c_str(), &pathStat) != 0)
{
return false;
}
return S_ISREG(pathStat.st_mode);
}
bool URIParser::isDirectory() const
{
struct stat pathStat{};
if (stat(getFilePath().c_str(), &pathStat) != 0)
{
return false;
}
return S_ISDIR(pathStat.st_mode);
}
bool URIParser::isValid() const
{
struct stat pathStat{};
return stat(getFilePath().c_str(), &pathStat) == 0;
}