diff --git a/include/lnm/http/route.h b/include/lnm/http/route.h index 2d87a1b..f121b96 100644 --- a/include/lnm/http/route.h +++ b/include/lnm/http/route.h @@ -49,23 +49,11 @@ lnm_err lnm_http_router_add(lnm_http_route **out, lnm_http_router *http_router, lnm_http_method method, const char *path); /** - * Checks whether the two routers have any conflicting parts. + * Add all of the child router's routes to the parent router, under the given + * route prefix. */ -bool lnm_http_router_conflicts(const lnm_http_router *r1, - const lnm_http_router *r2); - -/** - * Merge two routers, with the result ending up in r1. This is equivalent to - * nesting a router on '/'. - */ -lnm_err lnm_http_router_merge(lnm_http_router *r1, lnm_http_router *r2); - -/** - * Integrate the child router into the parent routing, mounting its paths on the - * given prefix. - */ -lnm_err lnm_http_router_nest(lnm_http_router *parent, lnm_http_router *child, - const char *prefix); +lnm_err lnm_http_router_nest(lnm_http_router *parent, + const lnm_http_router *child, const char *prefix); lnm_http_route_err lnm_http_router_route(lnm_http_route_match *out, const lnm_http_router *router, diff --git a/src/http/lnm_http_router.c b/src/http/lnm_http_router.c index fec6c2e..ce15d9a 100644 --- a/src/http/lnm_http_router.c +++ b/src/http/lnm_http_router.c @@ -28,7 +28,6 @@ void lnm_http_router_free(lnm_http_router *router) { for (size_t i = 0; i < lnm_http_method_total; i++) { lnm_http_route_free(router->routes[i]); - lnm_http_route_free(router->multi_segment_routes[i]); } free(router); @@ -288,95 +287,3 @@ lnm_http_route_match_get(lnm_http_route_match *match, const char *key) { return &match->key_segments[trie->index]; } - -bool lnm_http_router_conflicts(const lnm_http_router *r1, - const lnm_http_router *r2) { - // First check the literal routes for the routers - for (lnm_http_method m = 0; m < lnm_http_method_total; m++) { - if ((r1->routes[m] != NULL && r2->routes[m] != NULL) || - (r1->multi_segment_routes[m] != NULL && - r2->multi_segment_routes[m] != NULL)) { - return true; - } - } - - if ((r1->single_segment_child != NULL && r2->single_segment_child != NULL) && - lnm_http_router_conflicts(r1->single_segment_child, - r2->single_segment_child)) { - return true; - } - - for (unsigned char c = 0; c < 128; c++) { - if ((r1->exact_children[c] != NULL && r2->exact_children[c] != NULL) && - lnm_http_router_conflicts(r1->exact_children[c], - r2->exact_children[c])) { - return true; - } - } - - return false; -} - -void __lnm_http_router_merge(lnm_http_router *r1, lnm_http_router *r2) { - for (lnm_http_method m = 0; m < lnm_http_method_total; m++) { - if (r2->routes[m] != NULL) { - r1->routes[m] = r2->routes[m]; - } - - if (r2->multi_segment_routes[m] != NULL) { - r1->multi_segment_routes[m] = r2->multi_segment_routes[m]; - } - } - - if (r1->single_segment_child != NULL && r2->single_segment_child != NULL) { - __lnm_http_router_merge(r1->single_segment_child, r2->single_segment_child); - } else if (r2->single_segment_child != NULL) { - r1->single_segment_child = r2->single_segment_child; - } - - for (unsigned char c = 0; c < 128; c++) { - if (r1->exact_children[c] != NULL && r2->exact_children[c] != NULL) { - __lnm_http_router_merge(r1->exact_children[c], r2->exact_children[c]); - } else if (r2->exact_children[c] != NULL) { - r1->exact_children[c] = r2->exact_children[c]; - } - } - - r1->represents_route = r1->represents_route || r2->represents_route; - - free(r2); -} - -lnm_err lnm_http_router_merge(lnm_http_router *r1, lnm_http_router *r2) { - if (lnm_http_router_conflicts(r1, r2)) { - return lnm_err_overlapping_route; - } - - __lnm_http_router_merge(r1, r2); - - return lnm_err_ok; -} - -lnm_err lnm_http_router_nest(lnm_http_router *parent, lnm_http_router *child, - const char *prefix) { - if (!is_ascii(prefix) || prefix[0] != '/') { - return lnm_err_invalid_route; - } - - lnm_http_router *router = parent; - - // The child router's routes are also mounted on '/', so we stop one earlier - // as we need to merge it with the router representing the '/' - while (*prefix != '\0') { - unsigned char c = *prefix; - - if (router->exact_children[c] == NULL) { - LNM_RES(lnm_http_router_init(&router->exact_children[c])); - } - - router = router->exact_children[c]; - prefix++; - } - - return lnm_http_router_merge(router, child); -} diff --git a/test/routing.c b/test/routing.c index 805a856..e133f4b 100644 --- a/test/routing.c +++ b/test/routing.c @@ -1,5 +1,3 @@ -#include "lnm/common.h" -#include "lnm/http/route.h" #include "test.h" #include "lnm/http/loop.h" @@ -53,56 +51,10 @@ void test_routing_star() { TEST_CHECK(lnm_http_router_route(&match, router, lnm_http_method_get, "/hello/world") == lnm_http_route_err_match); TEST_CHECK(match.key_segments[0].start == 1); TEST_CHECK(match.key_segments[0].len == 11); - - lnm_http_router_free(router); -} - -void test_routing_merge() { - lnm_http_router *rtr1, *rtr2; - lnm_http_route *rt1, *rt2; - lnm_http_route_match match; - - TEST_CHECK(lnm_http_router_init(&rtr1) == lnm_err_ok); - TEST_CHECK(lnm_http_router_init(&rtr2) == lnm_err_ok); - - TEST_CHECK(lnm_http_router_add(&rt1, rtr1, lnm_http_method_get, "/*key") == lnm_err_ok); - TEST_CHECK(lnm_http_router_add(NULL, rtr1, lnm_http_method_get, "/:key/hello") == lnm_err_ok); - TEST_CHECK(lnm_http_router_add(&rt2, rtr2, lnm_http_method_get, "/test2") == lnm_err_ok); - TEST_CHECK(lnm_http_router_add(NULL, rtr2, lnm_http_method_get, "/:key/hello2") == lnm_err_ok); - - TEST_CHECK(lnm_http_router_merge(rtr1, rtr2) == lnm_err_ok); - - TEST_CHECK(lnm_http_router_route(&match, rtr1, lnm_http_method_get, "/some/thing") == lnm_http_route_err_match); - TEST_CHECK(match.route == rt1); - - TEST_CHECK(lnm_http_router_route(&match, rtr1, lnm_http_method_get, "/test2") == lnm_http_route_err_match); - TEST_CHECK(match.route == rt2); -} - -void test_routing_nest() { - lnm_http_router *r1, *r2; - lnm_http_route_match match; - - TEST_CHECK(lnm_http_router_init(&r1) == lnm_err_ok); - TEST_CHECK(lnm_http_router_init(&r2) == lnm_err_ok); - - TEST_CHECK(lnm_http_router_add(NULL, r1, lnm_http_method_get, "/*key") == lnm_err_ok); - TEST_CHECK(lnm_http_router_add(NULL, r2, lnm_http_method_get, "/test/test2") == lnm_err_ok); - - TEST_CHECK(lnm_http_router_nest(r2, r1, "/test") == lnm_err_ok); - - TEST_CHECK(lnm_http_router_route(&match, r2, lnm_http_method_get, "/test/test_var/secondvar") == lnm_http_route_err_match); - TEST_CHECK(match.key_segments[0].start == 6); - TEST_CHECK(match.key_segments[0].len == 18); - - TEST_CHECK(lnm_http_router_route(&match, r2, lnm_http_method_get, "/test/test2") == lnm_http_route_err_match); - } TEST_LIST = { { "routing simple", test_routing_simple }, { "routing star", test_routing_star }, - { "routing merge", test_routing_merge }, - { "routing nest", test_routing_nest }, { NULL, NULL } };