diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-09-17 00:41:45 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-09-17 00:41:45 +0100 |
commit | 9e5ca43dc7ffb9f7e9d01943d70c594479cda805 (patch) | |
tree | f18a88db3788448a9e6109130a9edd98b6d1bf4b | |
parent | Remove previous serializer before adding replacement (diff) | |
download | icespider-9e5ca43dc7ffb9f7e9d01943d70c594479cda805.tar.bz2 icespider-9e5ca43dc7ffb9f7e9d01943d70c594479cda805.tar.xz icespider-9e5ca43dc7ffb9f7e9d01943d70c594479cda805.zip |
Refactor routes into a flat list so we can correctly detect matching routes, but no method
-rw-r--r-- | icespider/core/core.cpp | 53 | ||||
-rw-r--r-- | icespider/core/core.h | 7 | ||||
-rw-r--r-- | icespider/unittests/testApp.cpp | 22 |
3 files changed, 40 insertions, 42 deletions
diff --git a/icespider/core/core.cpp b/icespider/core/core.cpp index 646ac57..da6a53d 100644 --- a/icespider/core/core.cpp +++ b/icespider/core/core.cpp @@ -5,6 +5,17 @@ namespace IceSpider { const boost::filesystem::path Core::defaultConfig("config/ice.properties"); + static + bool + operator/=(const PathElements & pathparts, const IRouteHandler * r) + { + auto rpi = r->parts.begin(); + for (auto ppi = pathparts.begin(); ppi != pathparts.end(); ++ppi, ++rpi) { + if (!(*rpi)->matches(*ppi)) return false; + } + return true; + } + Core::Core(int argc, char ** argv) { Ice::InitializationData id; @@ -14,27 +25,23 @@ namespace IceSpider { } communicator = Ice::initialize(id); - // Big enough to map all the request methods (an empty of zero lenght routes as default) - routes.resize(HttpMethod::OPTIONS + 1, {{ }}); // Initialize routes for (const auto & rp : AdHoc::PluginManager::getDefault()->getAll<RouteHandlerFactory>()) { auto r = rp->implementation()->create(this); - auto & mroutes = routes[r->method]; - if (mroutes.size() <= r->pathElementCount()) { - mroutes.resize(r->pathElementCount() + 1); + if (routes.size() <= r->pathElementCount()) { + routes.resize(r->pathElementCount() + 1); } - mroutes[r->pathElementCount()].push_back(r); + auto & lroutes = routes[r->pathElementCount()]; + lroutes.push_back(r); } } Core::~Core() { if (communicator) communicator->destroy(); - for (auto m : routes) { - for (auto l : m) { - for (auto r : l) { - delete r; - } + for (auto l : routes) { + for (auto r : l) { + delete r; } } } @@ -55,24 +62,26 @@ namespace IceSpider { Core::findRoute(const IHttpRequest * request) const { const auto & pathparts = request->getRequestPath(); - const auto & mroutes = routes[request->getRequestMethod()]; - if (pathparts.size() >= mroutes.size()) { + if (pathparts.size() >= routes.size()) { // Not found error return NULL; } - const auto & routeSet = mroutes[pathparts.size()]; - auto ri = std::find_if(routeSet.begin(), routeSet.end(), [&pathparts](const auto & r) { - auto rpi = r->parts.begin(); - for (auto ppi = pathparts.begin(); ppi != pathparts.end(); ++ppi, ++rpi) { - if (!(*rpi)->matches(*ppi)) return false; + const auto & routeSet = routes[pathparts.size()]; + bool match = false; + for (const auto & r : routeSet) { + if (pathparts /= r) { + if (r->method == request->getRequestMethod()) { + return r; + } + match = true; } - return true; - }); - if (ri == routeSet.end()) { + } + if (!match) { // Not found error return NULL; } - return (*ri); + // Method not allowed + return NULL; } Ice::ObjectPrx diff --git a/icespider/core/core.h b/icespider/core/core.h index 0a888a6..77d338e 100644 --- a/icespider/core/core.h +++ b/icespider/core/core.h @@ -10,9 +10,8 @@ namespace IceSpider { class DLL_PUBLIC Core { public: - typedef std::vector<const IRouteHandler *> Routes; - typedef std::vector<Routes> LengthRoutes; - typedef std::vector<LengthRoutes> MethodRoutes; + typedef std::vector<const IRouteHandler *> LengthRoutes; + typedef std::vector<LengthRoutes> Routes; Core(int = 0, char ** = NULL); ~Core(); @@ -28,7 +27,7 @@ namespace IceSpider { return Interface::ProxyType::uncheckedCast(getProxy(typeid(Interface).name())); } - MethodRoutes routes; + Routes routes; Ice::CommunicatorPtr communicator; static const boost::filesystem::path defaultConfig; diff --git a/icespider/unittests/testApp.cpp b/icespider/unittests/testApp.cpp index 5db7cfd..0c44f5e 100644 --- a/icespider/unittests/testApp.cpp +++ b/icespider/unittests/testApp.cpp @@ -87,22 +87,12 @@ BOOST_FIXTURE_TEST_SUITE(c, Core); BOOST_AUTO_TEST_CASE( testCoreSettings ) { - BOOST_REQUIRE_EQUAL(6, routes.size()); - BOOST_REQUIRE_EQUAL(5, routes[HttpMethod::GET].size()); - BOOST_REQUIRE_EQUAL(1, routes[HttpMethod::GET][0].size()); - BOOST_REQUIRE_EQUAL(1, routes[HttpMethod::GET][1].size()); - BOOST_REQUIRE_EQUAL(1, routes[HttpMethod::GET][2].size()); - BOOST_REQUIRE_EQUAL(2, routes[HttpMethod::GET][3].size()); - BOOST_REQUIRE_EQUAL(2, routes[HttpMethod::GET][4].size()); - BOOST_REQUIRE_EQUAL(1, routes[HttpMethod::HEAD].size()); - BOOST_REQUIRE_EQUAL(2, routes[HttpMethod::POST].size()); - BOOST_REQUIRE_EQUAL(0, routes[HttpMethod::POST][0].size()); - BOOST_REQUIRE_EQUAL(1, routes[HttpMethod::POST][1].size()); - BOOST_REQUIRE_EQUAL(1, routes[HttpMethod::PUT].size()); - BOOST_REQUIRE_EQUAL(2, routes[HttpMethod::DELETE].size()); - BOOST_REQUIRE_EQUAL(0, routes[HttpMethod::DELETE][0].size()); - BOOST_REQUIRE_EQUAL(1, routes[HttpMethod::DELETE][1].size()); - BOOST_REQUIRE_EQUAL(1, routes[HttpMethod::OPTIONS].size()); + BOOST_REQUIRE_EQUAL(5, routes.size()); + BOOST_REQUIRE_EQUAL(1, routes[0].size()); + BOOST_REQUIRE_EQUAL(3, routes[1].size()); + BOOST_REQUIRE_EQUAL(1, routes[2].size()); + BOOST_REQUIRE_EQUAL(2, routes[3].size()); + BOOST_REQUIRE_EQUAL(2, routes[4].size()); } BOOST_AUTO_TEST_CASE( testFindRoutes ) |