From cf4451740f24f6a1a9fcff50fcd8dd7c089a7ca8 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Sat, 2 Mar 2024 11:26:51 +0100 Subject: [PATCH] feat(routing): implement router nesting --- src/http/lnm_http_router.c | 64 +++++--------------------------------- test/routing.c | 11 +++---- 2 files changed, 12 insertions(+), 63 deletions(-) diff --git a/src/http/lnm_http_router.c b/src/http/lnm_http_router.c index 552369c..fec6c2e 100644 --- a/src/http/lnm_http_router.c +++ b/src/http/lnm_http_router.c @@ -359,74 +359,24 @@ lnm_err lnm_http_router_merge(lnm_http_router *r1, lnm_http_router *r2) { lnm_err lnm_http_router_nest(lnm_http_router *parent, lnm_http_router *child, const char *prefix) { - size_t prefix_len = strlen(prefix); - - if (!is_ascii(prefix) || prefix[0] != '/' || prefix[prefix_len - 1] == '/') { + if (!is_ascii(prefix) || prefix[0] != '/') { return lnm_err_invalid_route; } - lnm_http_router *merge_target = parent; + 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 + 1) != '\0') { + while (*prefix != '\0') { unsigned char c = *prefix; - if (merge_target->exact_children[c] == NULL) { - LNM_RES(lnm_http_router_init(&merge_target->exact_children[c])); + if (router->exact_children[c] == NULL) { + LNM_RES(lnm_http_router_init(&router->exact_children[c])); } - merge_target = merge_target->exact_children[c]; + router = router->exact_children[c]; prefix++; } - // We check whether there are any conflicts between the child and the existing - // router - bool conflicting = merge_target->single_segment_child != NULL && - child->single_segment_child != NULL; - - for (lnm_http_method m = 0; !conflicting && m < lnm_http_method_total; m++) { - conflicting = - conflicting || - (merge_target->routes[m] != NULL && child->routes[m] != NULL) || - (merge_target->multi_segment_routes[m] != NULL && - child->multi_segment_routes[m] != NULL); - } - - for (unsigned char c = 0; !conflicting && c < 128; c++) { - conflicting = conflicting || (merge_target->exact_children[c] != NULL && - child->exact_children[c] != NULL); - } - - if (conflicting) { - return lnm_err_overlapping_route; - } - - // Merge routers - merge_target->represents_route = - merge_target->represents_route || child->represents_route; - - if (child->single_segment_child != NULL) { - merge_target->single_segment_child = child->single_segment_child; - } - - for (lnm_http_method m = 0; m < lnm_http_method_total; m++) { - if (child->routes[m] != NULL) { - merge_target->routes[m] = child->routes[m]; - } - - if (child->multi_segment_routes[m] != NULL) { - merge_target->multi_segment_routes[m] = child->multi_segment_routes[m]; - } - } - - for (unsigned char c = 0; c < 128; c++) { - if (child->exact_children[c] != NULL) { - merge_target->exact_children[c] = child->exact_children[c]; - } - } - - free(child); - - return lnm_err_ok; + return lnm_http_router_merge(router, child); } diff --git a/test/routing.c b/test/routing.c index b87a243..805a856 100644 --- a/test/routing.c +++ b/test/routing.c @@ -80,18 +80,17 @@ void test_routing_merge() { } void test_routing_nest() { - lnm_http_router *r1; + 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); - - lnm_http_router *r2; - TEST_CHECK(lnm_http_router_init(&r2) == 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); - lnm_http_route_match match; 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); @@ -104,6 +103,6 @@ TEST_LIST = { { "routing simple", test_routing_simple }, { "routing star", test_routing_star }, { "routing merge", test_routing_merge }, - /* { "routing nest", test_routing_nest }, */ + { "routing nest", test_routing_nest }, { NULL, NULL } };