1 #pragma once 2 /* @file 3 * @brief Defines router class and support structures 4 */ 5 #ifdef HAVE_CXX11 6 #include <functional> 7 #include <tuple> 8 #define HAVE_CPP_FUNC_PTR 9 #define IGNORE std::ignore 10 namespace funcptr = std; 11 #else 12 #ifdef HAVE_BOOST 13 #include <boost/function.hpp> 14 #include <boost/tuple/tuple.hpp> 15 #define IGNORE boost::tuples::ignore 16 namespace funcptr = boost; 17 #define HAVE_CPP_FUNC_PTR 18 #else 19 #warning "You need to configure with boost or have C++11 capable compiler for router" 20 #endif 21 #endif 22 23 #ifdef HAVE_CPP_FUNC_PTR 24 #include <vector> 25 #include <utility> 26 27 namespace YaHTTP { 28 typedef funcptr::function <void(Request* req, Response* resp)> THandlerFunction; //!< Handler function pointer 29 typedef funcptr::tuple<std::string, std::string, THandlerFunction, std::string> TRoute; //!< Route tuple (method, urlmask, handler, name) 30 typedef std::vector<TRoute> TRouteList; //!< List of routes in order of evaluation 31 32 /*! Implements simple router. 33 34 This class implements a router for masked urls. The URL mask syntax is as of follows 35 36 /<masked>/url<number>/<hi>.<format> 37 38 You can use <*param> to denote that everything will be matched and consumed into the parameter, including slash (/). Use <*> to denote that URL 39 is consumed but not stored. Note that only path is matched, scheme, host and url parameters are ignored. 40 */ 41 class Router { 42 private: Router()43 Router() {}; 44 static Router router; //<! Singleton instance of Router 45 public: 46 void map(const std::string& method, const std::string& url, THandlerFunction handler, const std::string& name); //<! Instance method for mapping urls 47 bool route(Request *req, THandlerFunction& handler); //<! Instance method for performing routing 48 void printRoutes(std::ostream &os); //<! Instance method for printing routes 49 std::pair<std::string, std::string> urlFor(const std::string &name, const strstr_map_t& arguments); //<! Instance method for generating paths 50 51 /*! Map an URL. 52 If method is left empty, it will match any method. Name is also optional, but needed if you want to find it for making URLs 53 */ Map(const std::string & method,const std::string & url,THandlerFunction handler,const std::string & name="")54 static void Map(const std::string& method, const std::string& url, THandlerFunction handler, const std::string& name = "") { router.map(method, url, handler, name); }; Get(const std::string & url,THandlerFunction handler,const std::string & name="")55 static void Get(const std::string& url, THandlerFunction handler, const std::string& name = "") { router.map("GET", url, handler, name); }; //<! Helper for mapping GET Post(const std::string & url,THandlerFunction handler,const std::string & name="")56 static void Post(const std::string& url, THandlerFunction handler, const std::string& name = "") { router.map("POST", url, handler, name); }; //<! Helper for mapping POST Put(const std::string & url,THandlerFunction handler,const std::string & name="")57 static void Put(const std::string& url, THandlerFunction handler, const std::string& name = "") { router.map("PUT", url, handler, name); }; //<! Helper for mapping PUT Patch(const std::string & url,THandlerFunction handler,const std::string & name="")58 static void Patch(const std::string& url, THandlerFunction handler, const std::string& name = "") { router.map("PATCH", url, handler, name); }; //<! Helper for mapping PATCH Delete(const std::string & url,THandlerFunction handler,const std::string & name="")59 static void Delete(const std::string& url, THandlerFunction handler, const std::string& name = "") { router.map("DELETE", url, handler, name); }; //<! Helper for mapping DELETE Any(const std::string & url,THandlerFunction handler,const std::string & name="")60 static void Any(const std::string& url, THandlerFunction handler, const std::string& name = "") { router.map("", url, handler, name); }; //<! Helper for mapping any method 61 Route(Request * req,THandlerFunction & handler)62 static bool Route(Request *req, THandlerFunction& handler) { return router.route(req, handler); }; //<! Performs routing based on req->url.path PrintRoutes(std::ostream & os)63 static void PrintRoutes(std::ostream &os) { router.printRoutes(os); }; //<! Prints all known routes to given output stream 64 URLFor(const std::string & name,const strstr_map_t & arguments)65 static std::pair<std::string, std::string> URLFor(const std::string &name, const strstr_map_t& arguments) { return router.urlFor(name,arguments); }; //<! Generates url from named route and arguments. Missing arguments are assumed empty GetRoutes()66 static const TRouteList& GetRoutes() { return router.routes; } //<! Reference to route list Clear()67 static void Clear() { router.routes.clear(); } //<! Clear all routes 68 69 TRouteList routes; //<! Instance variable for routes 70 }; 71 }; 72 #endif 73