diff options
| author | Roland Reichwein <mail@reichwein.it> | 2020-05-15 18:59:19 +0200 | 
|---|---|---|
| committer | Roland Reichwein <mail@reichwein.it> | 2020-05-15 18:59:19 +0200 | 
| commit | 48908fb0bba69404dfd86d1af3b9ace1e0d598c9 (patch) | |
| tree | e8b60f5dcb692d1840e9c948b92689c1c3c0c284 /config.cpp | |
| parent | 2a3c27aadee91cd7b179e762ef0fe99128345bd1 (diff) | |
Speedup GetPath()
Diffstat (limited to 'config.cpp')
| -rw-r--r-- | config.cpp | 88 | 
1 files changed, 52 insertions, 36 deletions
| @@ -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; | 
