/*********************************/ /* */ /* o.riabenkyi@gmain.com */ /* */ /*********************************/ #include "config/ServerConfig.hpp" #include namespace { // Hard code-level default, used when 'client_max_body_size' is not set. const size_t kDefaultClientMaxBodySize = 1000000; } // namespace ServerConfig::ServerConfig() : _listens(), _serverNames(), _root(), _clientMaxBodySize(kDefaultClientMaxBodySize), _errorPages(), _locations() {} void ServerConfig::addListen(const std::string &host, int port) { Listen listen; listen.host = host; listen.port = port; _listens.push_back(listen); } void ServerConfig::addServerName(const std::string &name) { _serverNames.push_back(name); } void ServerConfig::setRoot(const std::string &root) { _root = root; } void ServerConfig::setClientMaxBodySize(size_t size) { _clientMaxBodySize = size; } void ServerConfig::addErrorPage(int code, const std::string &path) { _errorPages[code] = path; } void ServerConfig::addLocation(const LocationConfig &location) { _locations.push_back(location); } const std::vector &ServerConfig::getListens() const { return _listens; } const std::vector &ServerConfig::getServerNames() const { return _serverNames; } const std::optional &ServerConfig::getRoot() const { return _root; } size_t ServerConfig::getClientMaxBodySize() const { return _clientMaxBodySize; } const std::map &ServerConfig::getErrorPages() const { return _errorPages; } const std::vector &ServerConfig::getLocations() const { return _locations; } const std::string &ServerConfig::resolveRoot(const LocationConfig &location) const { if (location.getRoot().has_value()) return *location.getRoot(); if (_root.has_value()) return *_root; throw std::runtime_error("no 'root' available for location '" + location.getPath() + "'"); } void ServerConfig::validate() const { if (_listens.empty()) throw std::runtime_error("server block must have at least one 'listen' directive"); for (std::vector::const_iterator it = _listens.begin(); it != _listens.end(); ++it) { if (it->port <= 0 || it->port > 65535) throw std::runtime_error("invalid port number in 'listen' directive"); } for (size_t i = 0; i < _locations.size(); ++i) { _locations[i].validate(); if (!_locations[i].getRoot().has_value() && !_root.has_value()) throw std::runtime_error("no 'root' defined for location '" + _locations[i].getPath() + "' and the server block has no fallback root either"); for (size_t j = i + 1; j < _locations.size(); ++j) { if (_locations[i].getPath() == _locations[j].getPath()) throw std::runtime_error("duplicate location path '" + _locations[i].getPath() + "'"); } } }