summaryrefslogtreecommitdiffhomepage
path: root/config.cpp
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-05-15 18:59:19 +0200
committerRoland Reichwein <mail@reichwein.it>2020-05-15 18:59:19 +0200
commit48908fb0bba69404dfd86d1af3b9ace1e0d598c9 (patch)
treee8b60f5dcb692d1840e9c948b92689c1c3c0c284 /config.cpp
parent2a3c27aadee91cd7b179e762ef0fe99128345bd1 (diff)
Speedup GetPath()
Diffstat (limited to 'config.cpp')
-rw-r--r--config.cpp88
1 files changed, 52 insertions, 36 deletions
diff --git a/config.cpp b/config.cpp
index 2ece1ef..ed28ea9 100644
--- a/config.cpp
+++ b/config.cpp
@@ -56,15 +56,16 @@ void Config::readConfigfile(std::string filename)
for (const auto& site: element.second) {
if (site.first != "site"s)
throw std::runtime_error("<site> expected in <sites>");
+ std::string site_name;
Site site_struct;
for (const auto& x: site.second) {
if (x.first == "name"s) {
- if (site_struct.name == "")
- site_struct.name = x.second.data();
+ if (site_name == "")
+ site_name = x.second.data();
else
throw std::runtime_error("Found double site name: "s + x.second.data());
} else if (x.first == "host"s) {
- if (std::find(site_struct.hosts.begin(), site_struct.hosts.end(), x.second.data()) == site_struct.hosts.end())
+ if (site_struct.hosts.find(x.second.data()) == site_struct.hosts.end())
site_struct.hosts.insert(x.second.data());
else
throw std::runtime_error("Found double site host element: "s + x.second.data());
@@ -110,10 +111,12 @@ void Config::readConfigfile(std::string filename)
} else
throw std::runtime_error("Unknown element: "s + x.first);
}
- if (std::find_if(m_sites.begin(), m_sites.end(), [&](const Site& site){return site.name == site_struct.name;}) == m_sites.end())
- m_sites.push_back(site_struct);
+ if (site_name.empty())
+ throw std::runtime_error("Empty site name");
+ if (m_sites.find(site_name) == m_sites.end())
+ m_sites[site_name] = site_struct;
else
- throw std::runtime_error("Found double site spec: "s + site_struct.name);
+ throw std::runtime_error("Found double site spec: "s + site_name);
}
} else if (element.first == "sockets"s) {
for (const auto& socket: element.second) {
@@ -140,10 +143,10 @@ void Config::readConfigfile(std::string filename)
throw std::runtime_error("Unknown protocol: "s + x.second.data());
} else if (x.first == "site"s) {
std::string site {x.second.data()};
- if (std::find(socket_struct.serve_sites.begin(), socket_struct.serve_sites.end(), site) == socket_struct.serve_sites.end()) {
- socket_struct.serve_sites.push_back(site);
+ if (socket_struct.serve_sites.find(site) == socket_struct.serve_sites.end()) {
+ socket_struct.serve_sites.insert(site);
} else {
- throw std::runtime_error("Site "s + site + " already defined for "s + socket_struct.address + " port " + socket_struct.port);
+ throw std::runtime_error("Site "s + site + " already defined for "s + socket_struct.address + ", port " + socket_struct.port);
}
} else
throw std::runtime_error("Unknown element: "s + x.first);
@@ -161,10 +164,26 @@ void Config::readConfigfile(std::string filename)
for (auto& socket: m_sockets) {
if (socket.serve_sites.empty()) {
for (const auto& site: m_sites) {
- socket.serve_sites.push_back(site.name);
+ socket.serve_sites.insert(site.first);
}
}
}
+
+ validate();
+}
+
+// just throws on inconsistency
+void Config::validate()
+{
+ // make sure all m_sockets.serve_sites are configured in m_sites
+
+ for (auto& socket: m_sockets) {
+ for (auto& serve_site: socket.serve_sites) {
+ if (m_sites.find(serve_site) == m_sites.end())
+ throw std::runtime_error("Found serve_site "s + serve_site + " without configured site"s);
+ }
+ }
+
}
Config::Config(const std::string& filename)
@@ -193,7 +212,7 @@ const std::vector<std::string>& Config::PluginDirectories() const
return m_plugin_directories;
}
-const std::vector<Site>& Config::Sites() const
+const std::unordered_map<std::string, Site>& Config::Sites() const
{
return m_sites;
}
@@ -217,21 +236,21 @@ void Config::dump() const
std::cout << std::endl;
for (const auto& site: m_sites) {
- std::cout << "Site: " << site.name << ":";
- for (const auto& host: site.hosts)
+ std::cout << "Site: " << site.first << ":";
+ for (const auto& host: site.second.hosts)
std::cout << " " << host;
std::cout << std::endl;
- if (site.paths.size() == 0)
+ if (site.second.paths.size() == 0)
std::cout << " Warning: No paths configured." << std::endl;
- for (const auto& path: site.paths) {
+ for (const auto& path: site.second.paths) {
std::cout << " Path: " << path.requested << std::endl;
for (const auto& param: path.params) {
std::cout << " " << param.first << ": " << param.second << std::endl;
}
}
- if (site.key_path != ""s) {
- std::cout << " Key: " << site.key_path.generic_string() << std::endl;
- std::cout << " Cert: " << site.cert_path.generic_string() << std::endl;
+ if (site.second.key_path != ""s) {
+ std::cout << " Key: " << site.second.key_path.generic_string() << std::endl;
+ std::cout << " Cert: " << site.second.cert_path.generic_string() << std::endl;
}
}
@@ -251,29 +270,26 @@ const Path& Config::GetPath(const Socket& socket, const std::string& requested_h
{
//boost::timer::auto_cpu_timer t;
- // TODO: speed this up
std::string host{requested_host};
const Path* result{nullptr};
size_t path_len{0}; // find longest matching prefix
RemovePortFromHostname(host);
- for (const auto& site: m_sites) {
- if (std::find(socket.serve_sites.begin(), socket.serve_sites.end(), site.name) != socket.serve_sites.end()) {
- for (const auto& m_host: site.hosts) {
- if (m_host == host) {
- for (const auto& path: site.paths) {
- if (boost::starts_with(requested_path, path.requested) &&
- ("/?"s.find(requested_path[path.requested.size()]) != std::string::npos ||
- requested_path[path.requested.size()] == 0 ||
- requested_path[path.requested.size() - 1] == '/'
- ) &&
- path.requested.size() > path_len)
- {
- path_len = path.requested.size();
- result = &path;
- }
- }
+ for (const auto& site_name: socket.serve_sites) {
+ const Site& site {m_sites.at(site_name)}; // omit error check: validation previously made sure this exists
+
+ if (site.hosts.find(host) != site.hosts.end()) {
+ for (const auto& path: site.paths) {
+ if (boost::starts_with(requested_path, path.requested) &&
+ ("/?"s.find(requested_path[path.requested.size()]) != std::string::npos ||
+ requested_path[path.requested.size()] == 0 ||
+ requested_path[path.requested.size() - 1] == '/'
+ ) &&
+ path.requested.size() > path_len)
+ {
+ path_len = path.requested.size();
+ result = &path;
}
}
}
@@ -288,7 +304,7 @@ const Path& Config::GetPath(const Socket& socket, const std::string& requested_h
bool Config::PluginIsConfigured(const std::string& name) const
{
for (const auto& site: m_sites) {
- for (const auto& path: site.paths) {
+ for (const auto& path: site.second.paths) {
auto it{path.params.find("plugin")};
if (it != path.params.end() && it->second == name)
return true;