#include <boost/program_options/variables_map.hpp>
#include <unordered_map>
-#include <vector>
-#include <seastar/core/future-util.hh>
namespace seastar {
* @param handler the desire handler
* @return it self
*/
- routes& put(operation_type type, const sstring& url,
- handler_base* handler) {
- //FIXME if a handler is already exists, it need to be
- // deleted to prevent memory leak
- _map[type][url] = handler;
- return *this;
- }
+ routes& put(operation_type type, const sstring& url, handler_base* handler);
+
+ /**
+ * removing a handler from exact match
+ * @param url the url to match (note that url should start with /)
+ * @return the current handler (to be removed by caller)
+ */
+ handler_base* drop(operation_type type, const sstring& url);
/**
* add a rule to be used.
* @return it self
*/
routes& add(match_rule* rule, operation_type type = GET) {
- _rules[type].push_back(rule);
+ _rules[type][_rover++] = rule;
return *this;
}
* @param url the request url
* @return the handler if exists or nullptr if it does not
*/
- handler_base* get_exact_match(operation_type type, const sstring& url) {
- return (_map[type].find(url) == _map[type].end()) ?
- nullptr : _map[type][url];
+ handler_base* get_exact_match(operation_type type, const sstring& url) const {
+ auto i = _map[type].find(url);
+ return (i == _map[type].end()) ? nullptr : i->second;
}
-private:
-
/**
* Search and return a handler by the operation type and url
* @param type the http operation type
handler_base* get_handler(operation_type type, const sstring& url,
parameters& params);
+private:
/**
* Normalize the url to remove the last / if exists
* and get the parameter part
sstring normalize_url(const sstring& url);
std::unordered_map<sstring, handler_base*> _map[NUM_OPERATION];
- std::vector<match_rule*> _rules[NUM_OPERATION];
+public:
+ using rule_cookie = uint64_t;
+private:
+ rule_cookie _rover = 0;
+ std::map<rule_cookie, match_rule*> _rules[NUM_OPERATION];
public:
using exception_handler_fun = std::function<std::unique_ptr<reply>(std::exception_ptr eptr)>;
using exception_handler_id = size_t;
*
*/
void add_alias(const path_description& old_path, const path_description& new_path);
+
+ /**
+ * Add a rule to be used.
+ * @param rule a rule to add
+ * @param type the operation type
+ * @return a cookie using which the rule can be removed
+ */
+ rule_cookie add_cookie(match_rule* rule, operation_type type) {
+ auto pos = _rover++;
+ _rules[type][pos] = rule;
+ return pos;
+ }
+
+ /**
+ * Del a rule by cookie
+ * @param cookie a cookie returned previously by add_cookie
+ * @param type the operation type
+ * @return the pointer to the rule
+ */
+ match_rule* del_cookie(rule_cookie cookie, operation_type type);
};
/**
*/
void verify_param(const httpd::request& req, const sstring& param);
+/**
+ * The handler_registration object facilitates registration and auto
+ * unregistration of an exact-match handler_base into \ref routes "routes"
+ */
+class handler_registration {
+ routes& _routes;
+ const sstring _url;
+ operation_type _op;
+
+public:
+ /**
+ * Registers the handler_base into routes with routes::put
+ * @param rs the routes object reference
+ * @param h the desire handler
+ * @param url the url to match
+ * @param op the operation type (`GET` by default)
+ */
+ handler_registration(routes& rs, handler_base& h, const sstring& url, operation_type op = GET);
+
+ /**
+ * Unregisters the handler from routes with routes::drop
+ */
+ ~handler_registration();
+};
+
+/**
+ * The rule_registration object facilitates registration and auto
+ * unregistration of a match_rule handler into \ref routes "routes"
+ */
+class rule_registration {
+ routes& _routes;
+ operation_type _op;
+ routes::rule_cookie _cookie;
+
+public:
+ /**
+ * Registers the match_rule into routes with routes::add_cookie
+ * @param rs the routes object reference
+ * @param rule a rule to add
+ * @param op the operation type (`GET` by default)
+ */
+ rule_registration(routes& rs, match_rule& rule, operation_type op = GET);
+
+ /**
+ * Unregisters the rule from routes with routes::del_cookie
+ */
+ ~rule_registration();
+};
+
}
}