summaryrefslogtreecommitdiff
path: root/httpd/dispatcher.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'httpd/dispatcher.cpp')
-rw-r--r--httpd/dispatcher.cpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/httpd/dispatcher.cpp b/httpd/dispatcher.cpp
new file mode 100644
index 0000000..8620e76
--- /dev/null
+++ b/httpd/dispatcher.cpp
@@ -0,0 +1,109 @@
+/* dispatcher.cpp
+ * Copyright (C) 2003-2005 Tommi Maekitalo
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
+ * NON-INFRINGEMENT. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "tnt/dispatcher.h"
+#include <tnt/httperror.h>
+#include <functional>
+#include <iterator>
+#include <algorithm>
+#include <cxxtools/log.h>
+
+log_define("tntnet.dispatcher")
+
+namespace tnt
+{
+
+void Dispatcher::addUrlMapEntry(const std::string& url, const CompidentType& ci)
+{
+ cxxtools::WrLock lock(rwlock);
+
+ urlmap.push_back(urlmap_type::value_type(regex(url), ci));
+}
+
+Compident Dispatcher::mapComp(const std::string& compUrl) const
+{
+ urlmap_type::const_iterator pos = urlmap.begin();
+ return mapCompNext(compUrl, pos);
+}
+
+namespace {
+ class regmatch_formatter : public std::unary_function<const std::string&, std::string>
+ {
+ public:
+ regex_smatch what;
+ std::string operator() (const std::string& s) const
+ { return what.format(s); }
+ };
+}
+
+Dispatcher::urlMapCacheType::size_type Dispatcher::maxUrlMapCache = 8192;
+
+Dispatcher::CompidentType Dispatcher::mapCompNext(const std::string& compUrl,
+ Dispatcher::urlmap_type::const_iterator& pos) const
+{
+ // check cache
+ urlMapCacheType::key_type cacheKey = urlMapCacheType::key_type(compUrl, pos);
+ urlMapCacheType::const_iterator um = urlMapCache.find(cacheKey);
+ if (um != urlMapCache.end())
+ return um->second;
+
+ // no cache hit
+ regmatch_formatter formatter;
+
+ for (; pos != urlmap.end(); ++pos)
+ {
+ if (pos->first.match(compUrl, formatter.what))
+ {
+ const CompidentType& src = pos->second;
+
+ CompidentType ci;
+ ci.libname = formatter(src.libname);
+ ci.compname = formatter(src.compname);
+ if (src.hasPathInfo())
+ ci.setPathInfo(formatter(src.getPathInfo()));
+ std::transform(src.getArgs().begin(), src.getArgs().end(),
+ std::back_inserter(ci.getArgsRef()), formatter);
+
+ // clear cache after maxUrlMapCache distict requests
+ if (urlMapCache.size() >= maxUrlMapCache)
+ {
+ log_warn("clear url-map-cache");
+ urlMapCache.clear();
+ }
+
+ urlMapCache.insert(urlMapCacheType::value_type(cacheKey, ci));
+
+ return ci;
+ }
+ }
+
+ throw NotFoundException(compUrl);
+}
+
+Dispatcher::CompidentType Dispatcher::PosType::getNext()
+{
+ if (first)
+ first = false;
+ else
+ ++pos;
+
+ return dis.mapCompNext(url, pos);
+}
+
+}