first config parse try

This commit is contained in:
whaffman 2025-09-14 21:15:32 +02:00
parent 48953b1c62
commit cb88b9dc13
11 changed files with 424 additions and 27 deletions

View File

@ -41,5 +41,11 @@
}
}
}
},
"files.associations": {
"hash_map": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"string_view": "cpp"
}
}

View File

@ -38,3 +38,44 @@ server {
cgi_pass /cgi-bin/;
cgi_ext .py .php;
}
server {
listen 80;
server_name mylocal;
root /var/www/html2;
index index.html index2.htm;
error_page 400 /400.html;
error_page 403 /403.html;
error_page 404 /404.html;
error_page 405 /405.html;
error_page 413 /413.html;
error_page 500 /500.html;
error_page 502 /502.html;
error_page 504 /504.html;
client_max_body_size 1M;
location / {
autoindex off;
index index.html;
allow_methods GET POST DELETE;
}
location /2uploads {
root /var/www/uploads;
autoindex on;
allow_methods GET POST;
}
location /2images {
root /var/www/images;
autoindex off;
index index.jpg;
allow_methods GET;
}
cgi_pass /cgi-bin/;
cgi_ext .py .php;
}

View File

@ -1,7 +1,11 @@
#include <iostream>
#include <webserv/config/ConfigManager.hpp>
#include <webserv/config/ServerConfig.hpp>
#include <webserv/config/utils.hpp>
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdexcept>
ConfigManager::ConfigManager() : _initialized(false)
{
@ -25,6 +29,95 @@ void ConfigManager::init(const std::string &filePath)
throw std::runtime_error("ConfigManager is already initialized.");
}
std::cout << "Initializing ConfigManager with file: " << filePath << '\n';
// parseConfigFile(filePath);
parseConfigFile(filePath);
_initialized = true;
}
void removeEmptyLines(std::string &str)
{
std::istringstream stream(str);
std::string line;
std::string result;
while (std::getline(stream, line))
{
if (!trim(line).empty())
{
result += line + '\n';
}
}
str = result;
}
void removeComments(std::string &str)
{
size_t pos = 0;
while ((pos = str.find('#', pos)) != std::string::npos)
{
size_t end = str.find('\n', pos);
if (end == std::string::npos)
{
str.erase(pos);
}
else
{
str.erase(pos, end - pos);
}
}
removeEmptyLines(str);
}
void ConfigManager::parseConfigFile(const std::string &filePath)
{
// Placeholder for actual file parsing logic
std::cout << "Parsing configuration file: " << filePath << '\n';
// Implement the parsing logic here
std::ifstream file(filePath);
if (!file.is_open())
{
throw std::runtime_error("Could not open config file: " + filePath);
}
std::stringstream buffer;
buffer << file.rdbuf();
std::string content = buffer.str();
removeComments(content);
std::string globalDeclarations;
size_t pos = 0;
while (true)
{
size_t serverPos = content.find("server", pos);
size_t bracePos = content.find('{', serverPos);
if (serverPos == std::string::npos || bracePos == std::string::npos)
{
// No more server blocks, remaining is global
globalDeclarations += content.substr(pos);
break;
}
// Add global declarations before this server block
globalDeclarations += content.substr(pos, serverPos - pos);
size_t closeBrace = findCorrespondingClosingBrace(content, bracePos);
if (closeBrace == std::string::npos)
{
throw std::runtime_error("Malformed block in config file.");
}
// Optionally parse the server block here
std::string serverBlock = content.substr(bracePos + 1, closeBrace - bracePos - 1);
serverConfigs.emplace_back(serverBlock);
pos = closeBrace + 1;
}
// parseGlobalDeclarations(globalDeclarations); // Implement this function to handle global config
std::cout << "Global Declarations:\n" << globalDeclarations << '\n';
file.close();
}
void ConfigManager::parseGlobalDeclarations(const std::string &declarations)
{
// Placeholder for actual global declarations parsing logic
std::cout << "Parsing global declarations:\n" << declarations << '\n';
// Implement the parsing logic here
}

View File

@ -1,26 +1,9 @@
#pragma once
#include <map>
#include <memory>
#include <string>
#include <vector>
struct LocationConfig
{
std::string path;
bool autoIndex;
std::string indexFile;
// Add other location-specific configurations as needed
};
struct ServerConfig
{
std::string host;
int port;
std::string root;
// Add other server-specific configurations as needed
std::unique_ptr<std::map<std::string, LocationConfig>> locations;
};
class ServerConfig;
class ConfigManager
{
@ -39,7 +22,7 @@ class ConfigManager
~ConfigManager();
std::vector<ServerConfig> serverConfigs;
// void parseConfigFile(const std::string &filePath);
// void parseServerBlock(const std::string &block);
// void parseLocationBlock(const std::string &block, ServerConfig &serverConfig);
void parseConfigFile(const std::string &filePath);
void parseGlobalDeclarations(const std::string &declarations);
};

View File

@ -0,0 +1,57 @@
#include <webserv/config/LocationConfig.hpp>
#include <webserv/config/utils.hpp>
#include <iostream>
#include <string>
#include <sstream>
LocationConfig::LocationConfig(const std::string &locationBlock)
: path(""), autoIndex(false), indexFile("")
{
parseLocationBlock(locationBlock);
}
void LocationConfig::parseLocationBlock(const std::string &block)
{
// Placeholder for actual location block parsing logic
std::cout << "Parsing location block:\n" << block << '\n';
// Implement the parsing logic here
parseDirectives(block);
}
void LocationConfig::parseDirectives(const std::string &declarations)
{
// Placeholder for actual directives parsing logic
std::cout << "Parsing location directives:\n" << declarations << '\n';
// Implement the parsing logic here
std::istringstream stream(declarations);
std::string line;
while (std::getline(stream, line))
{
std::string directive;
std::istringstream ss{trim(line)};
ss >> directive;
if (!directive.empty())
{
std::cout << "Directive: " << directive << '\n';
// Implement the parsing logic here
std::string value;
ss >> value;
if (directive == "autoindex")
{
autoIndex = (value == "on");
std::cout << "Set autoindex to " << (autoIndex ? "on" : "off") << '\n';
}
else if (directive == "index")
{
indexFile = value;
std::cout << "Set index file to " << indexFile << '\n';
}
else
{
directives[directive] = value;
}
}
}
}

View File

@ -0,0 +1,20 @@
#pragma once
#include <string>
#include <map>
class LocationConfig
{
public:
LocationConfig(const std::string &locationBlock);
private:
std::string path;
bool autoIndex;
std::string indexFile;
std::map<std::string, std::string> directives;
void parseLocationBlock(const std::string &block);
void parseDirectives(const std::string &declarations);
};

View File

@ -0,0 +1,123 @@
#include <webserv/config/ServerConfig.hpp>
#include <webserv/config/LocationConfig.hpp>
#include <webserv/config/utils.hpp>
#include <iostream>
#include <string>
#include <sstream>
ServerConfig::ServerConfig(std::string const &serverBlock)
: host(""), port(80), root("")
{
parseServerBlock(serverBlock);
}
void ServerConfig::parseServerBlock(const std::string &block)
{
// Placeholder for actual server block parsing logic
std::cout << "Parsing server block:\n";
// Placeholder for actual file parsing logic
std::string serverDeclarations;
size_t pos = 0;
while (true)
{
size_t locationPos = block.find("location", pos);
size_t bracePos = block.find('{', locationPos);
if (locationPos == std::string::npos || bracePos == std::string::npos)
{
// No more server blocks, remaining is global
serverDeclarations += block.substr(pos);
break;
}
std::string locationPath = trim(block.substr(locationPos, bracePos - (locationPos )));
// Add global declarations before this server block
serverDeclarations += block.substr(pos, locationPos - pos);
size_t closeBrace = findCorrespondingClosingBrace(block, bracePos);
if (closeBrace == std::string::npos)
{
throw std::runtime_error("Malformed block in config file.");
}
// Optionally parse the server block here
std::string serverBlock = block.substr(bracePos + 1, closeBrace - bracePos - 1);
locations.emplace(locationPath, LocationConfig(serverBlock));
pos = closeBrace + 1;
}
// parseGlobalDeclarations(Declarations); // Implement this function to handle global config
parseDirectives(serverDeclarations);
}
void ServerConfig::parseDirectives(const std::string &declarations)
{
// Placeholder for actual directives parsing logic
std::cout << "Parsing directives:\n" << declarations << '\n';
std::string line;
std::istringstream stream(declarations);
while (std::getline(stream, line))
{
std::string directive;
std::istringstream ss{trim(line)};
ss >> directive;
if (!directive.empty())
{
std::cout << "Directive: " << directive << '\n';
// Implement the parsing logic here
std::string value;
ss >> value;
if (directive == "listen")
{
port = std::stoi(value);
if (port < 1 || port > 65535)
{
throw std::runtime_error("Invalid port number: " + std::to_string(port));
}
std::cout << "Set port to " << port << '\n';
}
else if (directive == "root")
{
root = value;
std::cout << "Set root to " << root << '\n';
}
else if (directive == "server_name")
{
host = value;
std::cout << "Set server_name to " << host << '\n';
}
else if (directive == "cgi_pass")
{
cgi_pass = value;
std::cout << "Set cgi_pass to " << cgi_pass << '\n';
}
else if(directive =="cgi_ext")
{
cgi_ext = value;
std::cout << "Set cgi_ext to " << cgi_ext << '\n';
}
else if(directive == "index")
{
index_files.clear();
std::string indexFile;
while (ss >> indexFile)
{
index_files.push_back(indexFile);
std::cout << "Added index file: " << indexFile << '\n';
}
}
else if (directive == "error_page")
{
int statusCode = std::stoi(value);
std::string errorPagePath;
ss >> errorPagePath;
error_page[statusCode] = errorPagePath;
std::cout << "Set error_page for status " << statusCode << " to " << errorPagePath << '\n';
}
}
}
}

View File

@ -0,0 +1,28 @@
#pragma once
#include <map>
#include <string>
#include <vector>
#include <webserv/config/LocationConfig.hpp>
class ServerConfig
{
public:
ServerConfig(const std::string &serverBlock);
[[nodiscard]] LocationConfig getLocation(const std::string &path) const;
private:
std::string host;
int port;
std::string root;
std::string cgi_pass;
std::string cgi_ext;
std::map<int, std::string> error_page;
std::vector<std::string> index_files;
std::map<std::string, LocationConfig> locations;
void parseServerBlock(const std::string &block);
void parseDirectives(const std::string &declarations);
};

42
webserv/config/utils.cpp Normal file
View File

@ -0,0 +1,42 @@
#include <webserv/config/utils.hpp>
#include <string>
std::string trim(const std::string &str)
{
size_t first = str.find_first_not_of(" \t\n\r");
size_t last = str.find_last_not_of(" \t\n\r");
if (first == std::string::npos || last == std::string::npos)
{
return "";
}
return str.substr(first, last - first + 1);
}
size_t findCorrespondingClosingBrace(const std::string &str, size_t openPos)
{
int braceCount = 1;
if (str[openPos] != '{')
{
return std::string::npos; // Not an opening brace at the given position
}
for (size_t i = openPos + 1; i < str.size(); ++i)
{
if (str[i] == '{')
{
++braceCount;
}
else if (str[i] == '}')
{
--braceCount;
}
if (braceCount == 0)
{
return i;
}
}
return std::string::npos; // No matching closing brace found
}

6
webserv/config/utils.hpp Normal file
View File

@ -0,0 +1,6 @@
#pragma once
#include <string>
std::string trim(const std::string &str);
size_t findCorrespondingClosingBrace(const std::string &str, size_t openPos);

View File

@ -1,9 +1,7 @@
#include <system_error>
#include <webserv/config/ConfigManager.hpp>
#include <iostream>
#include <string>
#include <vector>
int main(int argc, char **argv)
{