From 43666a1183532f1a18386a0f41c61cc8a4df83d0 Mon Sep 17 00:00:00 2001 From: Yuansheng Date: Wed, 26 Jun 2019 23:06:32 +0800 Subject: [PATCH] feature: supported to match http scheme. --- include/r3.h | 8 +++- src/node.c | 6 +++ tests/Makefile.am | 3 ++ tests/check_http_scheme.c | 97 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 tests/check_http_scheme.c diff --git a/include/r3.h b/include/r3.h index 8bc4c63..8580d17 100644 --- a/include/r3.h +++ b/include/r3.h @@ -21,7 +21,7 @@ #if !defined(bool) && !defined(__cplusplus) typedef unsigned char bool; #endif -#ifndef false +#ifndef false # define false 0 #endif #ifndef true @@ -88,6 +88,8 @@ struct _R3Route { unsigned int remote_addr_v4; int remote_addr_v4_bits; + int http_scheme; // can be (SCHEME_HTTP or SCHEME_HTTP) + } __attribute__((aligned(64))); typedef struct _R3Entry match_entry; @@ -100,6 +102,8 @@ struct _R3Entry { r3_iovec_t host; // the request host r3_iovec_t remote_addr; + + int http_scheme; } __attribute__((aligned(64))); @@ -196,6 +200,8 @@ R3Route * r3_tree_match_route(const R3Node *n, match_entry * entry); #define METHOD_HEAD 2<<5 #define METHOD_OPTIONS 2<<6 +#define SCHEME_HTTP 2 +#define SCHEME_HTTPS 2<<1 int r3_pattern_to_opcode(const char * pattern, unsigned int len); diff --git a/src/node.c b/src/node.c index 8ccf79c..0c4cd80 100644 --- a/src/node.c +++ b/src/node.c @@ -888,6 +888,12 @@ inline int r3_route_cmp(const R3Route *r1, const match_entry *r2) { } } + if (r1->http_scheme) { + if (0 == (r1->http_scheme & r2->http_scheme) ) { + return -1; + } + } + if ( r1->host.len && r2->host.len ) { if (r1->host.len > r2->host.len) { return -1; diff --git a/tests/Makefile.am b/tests/Makefile.am index 6183225..baa4b15 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -33,6 +33,9 @@ check_host_SOURCES = check_host.c TESTS += check_remote_addr check_remote_addr_SOURCES = check_remote_addr.c +TESTS += check_http_scheme +check_http_scheme_SOURCES = check_http_scheme.c + if ENABLE_JSON TESTS += check_json diff --git a/tests/check_http_scheme.c b/tests/check_http_scheme.c new file mode 100644 index 0000000..ea22575 --- /dev/null +++ b/tests/check_http_scheme.c @@ -0,0 +1,97 @@ +#include "config.h" +#include +#include +#include +#include + +#include "r3.h" +#include "r3_slug.h" + +START_TEST (test_http_scheme) +{ + R3Node * n = r3_tree_create(10); + R3Route * route = NULL; + match_entry * entry; + R3Route *matched_route; + + char * uri0 = "/foo"; + route = r3_tree_insert_routel(n, 0, uri0, strlen(uri0), &uri0); + + char * uri1 = "/bar"; + route = r3_tree_insert_routel(n, 0, uri1, strlen(uri1), &uri1); + route->http_scheme = SCHEME_HTTPS; + + char * uri2 = "/boo"; + route = r3_tree_insert_routel(n, 0, uri2, strlen(uri2), &uri2); + route->http_scheme = SCHEME_HTTP | SCHEME_HTTPS; + + char * err = NULL; + r3_tree_compile(n, &err); + ck_assert(err == NULL); + + + entry = match_entry_create("/foo"); + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route != NULL); + ck_assert(matched_route->data == &uri0); + + entry = match_entry_create("/foo"); + entry->http_scheme = SCHEME_HTTP; + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route != NULL); + ck_assert(matched_route->data == &uri0); + + entry = match_entry_create("/bar"); + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route == NULL); + + entry = match_entry_create("/bar"); + entry->http_scheme = SCHEME_HTTP; + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route == NULL); + + entry = match_entry_create("/bar"); + entry->http_scheme = SCHEME_HTTPS; + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route != NULL); + ck_assert(matched_route->data == &uri1); + + entry = match_entry_create("/boo"); + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route == NULL); + + entry = match_entry_create("/boo"); + entry->http_scheme = SCHEME_HTTP; + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route != NULL); + ck_assert(matched_route->data == &uri2); + + entry = match_entry_create("/boo"); + entry->http_scheme = SCHEME_HTTPS; + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route != NULL); + ck_assert(matched_route->data == &uri2); + + r3_tree_free(n); +} +END_TEST + + + +Suite* r3_suite (void) { + Suite *suite = suite_create("r3 remote_addr tests"); + TCase *tcase = tcase_create("testcase"); + tcase_add_test(tcase, test_http_scheme); + suite_add_tcase(suite, tcase); + return suite; +} + +int main (int argc, char *argv[]) { + int number_failed; + Suite *suite = r3_suite(); + SRunner *runner = srunner_create(suite); + srunner_run_all(runner, CK_NORMAL); + number_failed = srunner_ntests_failed(runner); + srunner_free(runner); + return number_failed; +}