refactor(ServerConfig): update directive parsing and improve server socket binding
This commit is contained in:
parent
c9e74ca508
commit
1e80839864
@ -80,7 +80,7 @@ std::string Client::getResponse() const
|
|||||||
}
|
}
|
||||||
// further validation can be added here
|
// further validation can be added here
|
||||||
response += "Content-Length: 18\r\n\r\n";
|
response += "Content-Length: 18\r\n\r\n";
|
||||||
response += "Server port " + std::to_string(server_config_.getPort()) + "\r\n";
|
response += "Server port 8080\r\n";
|
||||||
|
|
||||||
Log::debug("Sending response:\n" + response);
|
Log::debug("Sending response:\n" + response);
|
||||||
return response;
|
return response;
|
||||||
|
|||||||
@ -2,6 +2,9 @@
|
|||||||
#include <webserv/config/ServerConfig.hpp>
|
#include <webserv/config/ServerConfig.hpp>
|
||||||
#include <webserv/config/utils.hpp> // for findCorrespondingClosingBrace, trim
|
#include <webserv/config/utils.hpp> // for findCorrespondingClosingBrace, trim
|
||||||
#include <webserv/log/Log.hpp> // for Log, LOCATION
|
#include <webserv/log/Log.hpp> // for Log, LOCATION
|
||||||
|
#include <webserv/config/directive/DirectiveFactory.hpp> // for DirectiveFactory
|
||||||
|
#include <webserv/config/directive/ADirective.hpp> // for ADirective
|
||||||
|
|
||||||
|
|
||||||
#include <cstddef> // for size_t
|
#include <cstddef> // for size_t
|
||||||
#include <sstream> // for basic_istringstream, basic_istream, istringstream
|
#include <sstream> // for basic_istringstream, basic_istream, istringstream
|
||||||
@ -54,92 +57,123 @@ void ServerConfig::parseServerBlock(const std::string &block)
|
|||||||
parseDirectives(serverDeclarations);
|
parseDirectives(serverDeclarations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void ServerConfig::parseDirectives(const std::string &declarations)
|
||||||
|
// {
|
||||||
|
// Log::info("Parsing server directives");
|
||||||
|
// std::string line;
|
||||||
|
// std::istringstream stream(declarations);
|
||||||
|
// while (std::getline(stream, line))
|
||||||
|
// {
|
||||||
|
// std::string directive;
|
||||||
|
// std::istringstream lineStream{line};
|
||||||
|
// lineStream >> directive;
|
||||||
|
// if (!directive.empty())
|
||||||
|
// {
|
||||||
|
// std::string value;
|
||||||
|
// lineStream >> value;
|
||||||
|
// if (directive == "listen")
|
||||||
|
// {
|
||||||
|
|
||||||
|
// port_ = std::stoi(value);
|
||||||
|
// if (port_ < 1 || port_ > 65535)
|
||||||
|
// {
|
||||||
|
// throw std::runtime_error("Invalid port number: " + std::to_string(port_));
|
||||||
|
// }
|
||||||
|
// Log::debug("Set port to " + std::to_string(port_));
|
||||||
|
// }
|
||||||
|
// else if (directive == "root")
|
||||||
|
// {
|
||||||
|
// root_ = value;
|
||||||
|
// Log::debug("Set root to " + root_);
|
||||||
|
// }
|
||||||
|
// else if (directive == "host")
|
||||||
|
// {
|
||||||
|
// host_ = value;
|
||||||
|
// Log::debug("Set host to " + host_);
|
||||||
|
// }
|
||||||
|
// else if (directive == "cgi_pass")
|
||||||
|
// {
|
||||||
|
// cgi_pass_ = value;
|
||||||
|
// Log::debug("Set cgi_pass to " + cgi_pass_);
|
||||||
|
// }
|
||||||
|
// else if (directive == "cgi_ext")
|
||||||
|
// {
|
||||||
|
// cgi_ext_ = value;
|
||||||
|
// Log::debug("Set cgi_ext to " + cgi_ext_);
|
||||||
|
// }
|
||||||
|
// else if (directive == "index")
|
||||||
|
// {
|
||||||
|
// index_files_.clear();
|
||||||
|
// std::string indexFile;
|
||||||
|
// while (lineStream >> indexFile)
|
||||||
|
// {
|
||||||
|
// index_files_.push_back(indexFile);
|
||||||
|
// Log::debug("Added index file: " + indexFile);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else if (directive == "error_page")
|
||||||
|
// {
|
||||||
|
// int statusCode = std::stoi("-1");
|
||||||
|
// std::string errorPagePath;
|
||||||
|
// lineStream >> errorPagePath;
|
||||||
|
// Log::debug("Set error_page for status " + std::to_string(statusCode) + " to " + errorPagePath);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// Log::warning("Unknown directive: " + directive);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const LocationConfig &ServerConfig::getLocation(const std::string &path) const
|
||||||
|
// {
|
||||||
|
// if (locations_.count(path) > 0) // NOLINT
|
||||||
|
// {
|
||||||
|
// return locations_.at(path);
|
||||||
|
// }
|
||||||
|
// Log::error("Location not found: " + path);
|
||||||
|
// throw std::runtime_error("Location not found: " + path);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::vector<std::string> ServerConfig::getLocationPaths() const
|
||||||
|
// {
|
||||||
|
// std::vector<std::string> paths;
|
||||||
|
// paths.reserve(locations_.size());
|
||||||
|
// for (const auto &pair : locations_)
|
||||||
|
// {
|
||||||
|
// paths.push_back(pair.first);
|
||||||
|
// }
|
||||||
|
// return paths;
|
||||||
|
// }
|
||||||
|
|
||||||
void ServerConfig::parseDirectives(const std::string &declarations)
|
void ServerConfig::parseDirectives(const std::string &declarations)
|
||||||
{
|
{
|
||||||
Log::info("Parsing server directives");
|
Log::trace(LOCATION);
|
||||||
|
std::stringstream ss(declarations);
|
||||||
std::string line;
|
std::string line;
|
||||||
std::istringstream stream(declarations);
|
while (ss.good())
|
||||||
while (std::getline(stream, line))
|
|
||||||
{
|
{
|
||||||
std::string directive;
|
std::getline(ss, line);
|
||||||
std::istringstream lineStream{line};
|
line = utils::trim(line);
|
||||||
lineStream >> directive;
|
if (line.empty())
|
||||||
if (!directive.empty())
|
|
||||||
{
|
{
|
||||||
std::string value;
|
continue;
|
||||||
lineStream >> value;
|
}
|
||||||
if (directive == "listen")
|
auto directive = DirectiveFactory::createDirective(line);
|
||||||
{
|
directives_.push_back(std::move(directive));
|
||||||
|
}
|
||||||
|
Log::info("Parsed " + std::to_string(directives_.size()) + " directives.", {{"declarations", declarations}});
|
||||||
|
}
|
||||||
|
|
||||||
port_ = std::stoi(value);
|
DirectiveValue ServerConfig::operator[](const std::string &directive) const
|
||||||
if (port_ < 1 || port_ > 65535)
|
{
|
||||||
{
|
for (const auto& dir : directives_)
|
||||||
throw std::runtime_error("Invalid port number: " + std::to_string(port_));
|
{
|
||||||
}
|
if (dir->getName() == directive)
|
||||||
Log::debug("Set port to " + std::to_string(port_));
|
{
|
||||||
}
|
return dir->get();
|
||||||
else if (directive == "root")
|
|
||||||
{
|
|
||||||
root_ = value;
|
|
||||||
Log::debug("Set root to " + root_);
|
|
||||||
}
|
|
||||||
else if (directive == "host")
|
|
||||||
{
|
|
||||||
host_ = value;
|
|
||||||
Log::debug("Set host to " + host_);
|
|
||||||
}
|
|
||||||
else if (directive == "cgi_pass")
|
|
||||||
{
|
|
||||||
cgi_pass_ = value;
|
|
||||||
Log::debug("Set cgi_pass to " + cgi_pass_);
|
|
||||||
}
|
|
||||||
else if (directive == "cgi_ext")
|
|
||||||
{
|
|
||||||
cgi_ext_ = value;
|
|
||||||
Log::debug("Set cgi_ext to " + cgi_ext_);
|
|
||||||
}
|
|
||||||
else if (directive == "index")
|
|
||||||
{
|
|
||||||
index_files_.clear();
|
|
||||||
std::string indexFile;
|
|
||||||
while (lineStream >> indexFile)
|
|
||||||
{
|
|
||||||
index_files_.push_back(indexFile);
|
|
||||||
Log::debug("Added index file: " + indexFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (directive == "error_page")
|
|
||||||
{
|
|
||||||
int statusCode = std::stoi("-1");
|
|
||||||
std::string errorPagePath;
|
|
||||||
lineStream >> errorPagePath;
|
|
||||||
Log::debug("Set error_page for status " + std::to_string(statusCode) + " to " + errorPagePath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log::warning("Unknown directive: " + directive);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
throw std::runtime_error("Directive not found: " + directive);
|
||||||
|
|
||||||
const LocationConfig &ServerConfig::getLocation(const std::string &path) const
|
|
||||||
{
|
|
||||||
if (locations_.count(path) > 0) // NOLINT
|
|
||||||
{
|
|
||||||
return locations_.at(path);
|
|
||||||
}
|
|
||||||
Log::error("Location not found: " + path);
|
|
||||||
throw std::runtime_error("Location not found: " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> ServerConfig::getLocationPaths() const
|
|
||||||
{
|
|
||||||
std::vector<std::string> paths;
|
|
||||||
paths.reserve(locations_.size());
|
|
||||||
for (const auto &pair : locations_)
|
|
||||||
{
|
|
||||||
paths.push_back(pair.first);
|
|
||||||
}
|
|
||||||
return paths;
|
|
||||||
}
|
}
|
||||||
@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "webserv/config/directive/ADirective.hpp"
|
||||||
#include <webserv/config/LocationConfig.hpp>
|
#include <webserv/config/LocationConfig.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -12,22 +14,24 @@ class ServerConfig
|
|||||||
public:
|
public:
|
||||||
ServerConfig(const std::string &serverBlock);
|
ServerConfig(const std::string &serverBlock);
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getHost() const { return host_; }
|
// [[nodiscard]] const std::string &getHost() const { return host_; }
|
||||||
|
|
||||||
[[nodiscard]] int getPort() const { return port_; }
|
// [[nodiscard]] int getPort() const { return port_; }
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getRoot() const { return root_; }
|
// [[nodiscard]] const std::string &getRoot() const { return root_; }
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getCgiPass() const { return cgi_pass_; }
|
// [[nodiscard]] const std::string &getCgiPass() const { return cgi_pass_; }
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getCgiExt() const { return cgi_ext_; }
|
// [[nodiscard]] const std::string &getCgiExt() const { return cgi_ext_; }
|
||||||
|
|
||||||
[[nodiscard]] const std::map<int, std::string> &getErrorPages() const { return error_page_; }
|
// [[nodiscard]] const std::map<int, std::string> &getErrorPages() const { return error_page_; }
|
||||||
|
|
||||||
[[nodiscard]] const std::vector<std::string> &getIndexFiles() const { return index_files_; }
|
// [[nodiscard]] const std::vector<std::string> &getIndexFiles() const { return index_files_; }
|
||||||
|
|
||||||
[[nodiscard]] const LocationConfig &getLocation(const std::string &path) const;
|
// [[nodiscard]] const LocationConfig &getLocation(const std::string &path) const;
|
||||||
[[nodiscard]] std::vector<std::string> getLocationPaths() const;
|
// [[nodiscard]] std::vector<std::string> getLocationPaths() const;
|
||||||
|
|
||||||
|
DirectiveValue operator[](const std::string &directive) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string host_;
|
std::string host_;
|
||||||
@ -38,6 +42,7 @@ class ServerConfig
|
|||||||
std::map<int, std::string> error_page_;
|
std::map<int, std::string> error_page_;
|
||||||
std::vector<std::string> index_files_;
|
std::vector<std::string> index_files_;
|
||||||
std::map<std::string, LocationConfig> locations_;
|
std::map<std::string, LocationConfig> locations_;
|
||||||
|
std::vector<std::unique_ptr<ADirective>> directives_;
|
||||||
|
|
||||||
void parseServerBlock(const std::string &block);
|
void parseServerBlock(const std::string &block);
|
||||||
void parseDirectives(const std::string &declarations);
|
void parseDirectives(const std::string &declarations);
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <any>
|
#include <any>
|
||||||
#include <array>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class DirectiveValue
|
class DirectiveValue
|
||||||
@ -40,7 +39,7 @@ class ADirective
|
|||||||
void setName(const std::string &name);
|
void setName(const std::string &name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string name_;
|
std::string name_; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Supported directives:
|
// Supported directives:
|
||||||
|
|||||||
@ -87,7 +87,7 @@ void Server::setupServerSocket(const ServerConfig &config)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::unique_ptr<Socket> serverSocket = std::make_unique<Socket>();
|
std::unique_ptr<Socket> serverSocket = std::make_unique<Socket>();
|
||||||
serverSocket->bind(config.getHost(), config.getPort());
|
serverSocket->bind(config["host"], config["listen"]);
|
||||||
serverSocket->listen(SOMAXCONN);
|
serverSocket->listen(SOMAXCONN);
|
||||||
int server_fd = serverSocket->getFd();
|
int server_fd = serverSocket->getFd();
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ void Server::setupServerSocket(const ServerConfig &config)
|
|||||||
|
|
||||||
listeners_.push_back(std::move(serverSocket));
|
listeners_.push_back(std::move(serverSocket));
|
||||||
fdToConfig_.insert({server_fd, std::cref(config)});
|
fdToConfig_.insert({server_fd, std::cref(config)});
|
||||||
Log::info("Server listening on " + config.getHost() + ":" + std::to_string(config.getPort()) + "...");
|
// Log::info("Server listening on " + std::string(config["host"]) + ":" + static_cast<std::string>(config["listen"]) + "...");
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user