Merge pull request #128 from iresty/bug-end-maybe-0-len
bugfix: the end matching length is 0.
This commit is contained in:
commit
e20e48a5ce
3 changed files with 42 additions and 30 deletions
56
src/node.c
56
src/node.c
|
@ -262,20 +262,8 @@ int r3_tree_compile_patterns(R3Node * n, char **errstr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static R3Node * r3_tree_matchl_base(const R3Node * n, const char * path,
|
||||||
|
unsigned int path_len, match_entry * entry, int is_end) {
|
||||||
|
|
||||||
/**
|
|
||||||
* This function matches the URL path and return the left node
|
|
||||||
*
|
|
||||||
* r3_tree_matchl returns NULL when the path does not match. returns *node when the path matches.
|
|
||||||
*
|
|
||||||
* @param node n the root of the tree
|
|
||||||
* @param char* path the URL path to dispatch
|
|
||||||
* @param int path_len the length of the URL path.
|
|
||||||
* @param match_entry* entry match_entry is used for saving the captured dynamic strings from pcre result.
|
|
||||||
*/
|
|
||||||
R3Node * r3_tree_matchl(const R3Node * n, const char * path, unsigned int path_len, match_entry * entry) {
|
|
||||||
info("try matching: %s\n", path);
|
info("try matching: %s\n", path);
|
||||||
|
|
||||||
R3Edge *e;
|
R3Edge *e;
|
||||||
|
@ -334,9 +322,12 @@ R3Node * r3_tree_matchl(const R3Node * n, const char * path, unsigned int path_l
|
||||||
if (entry) {
|
if (entry) {
|
||||||
str_array_append(&entry->vars , path, pp - path);
|
str_array_append(&entry->vars , path, pp - path);
|
||||||
}
|
}
|
||||||
|
restlen = pp_end - pp;
|
||||||
|
if (!restlen) {
|
||||||
return e->child && e->child->endpoint ? e->child : NULL;
|
return e->child && e->child->endpoint ? e->child : NULL;
|
||||||
}
|
}
|
||||||
|
return r3_tree_matchl_base(e->child, pp, restlen, entry, is_end);
|
||||||
|
}
|
||||||
|
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
|
@ -351,7 +342,7 @@ R3Node * r3_tree_matchl(const R3Node * n, const char * path, unsigned int path_l
|
||||||
int ov[ n->ov_cnt ];
|
int ov[ n->ov_cnt ];
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
info("pcre matching %s on %s\n", n->combined_pattern, path);
|
info("pcre matching %s on [%s]\n", n->combined_pattern, path);
|
||||||
|
|
||||||
rc = pcre_exec(
|
rc = pcre_exec(
|
||||||
n->pcre_pattern, /* the compiled pattern */
|
n->pcre_pattern, /* the compiled pattern */
|
||||||
|
@ -393,7 +384,7 @@ R3Node * r3_tree_matchl(const R3Node * n, const char * path, unsigned int path_l
|
||||||
substring_length = *(inv+1) - *inv;
|
substring_length = *(inv+1) - *inv;
|
||||||
|
|
||||||
// if it's not matched for this edge, just skip them quickly
|
// if it's not matched for this edge, just skip them quickly
|
||||||
if ( !substring_length ) {
|
if (!is_end && !substring_length) {
|
||||||
inv += 2;
|
inv += 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -419,7 +410,7 @@ R3Node * r3_tree_matchl(const R3Node * n, const char * path, unsigned int path_l
|
||||||
substring_length = *(inv+1) - *inv;
|
substring_length = *(inv+1) - *inv;
|
||||||
|
|
||||||
// if it's not matched for this edge, just skip them quickly
|
// if it's not matched for this edge, just skip them quickly
|
||||||
if ( !substring_length ) {
|
if (!is_end && !substring_length) {
|
||||||
inv += 2;
|
inv += 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -433,7 +424,7 @@ R3Node * r3_tree_matchl(const R3Node * n, const char * path, unsigned int path_l
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the length of orginal string: $0
|
// get the length of orginal string: $0
|
||||||
return r3_tree_matchl( e->child, path + (ov[1] - ov[0]), restlen, entry);
|
return r3_tree_matchl_base( e->child, path + (ov[1] - ov[0]), restlen, entry, is_end);
|
||||||
}
|
}
|
||||||
// does not match
|
// does not match
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -444,14 +435,39 @@ R3Node * r3_tree_matchl(const R3Node * n, const char * path, unsigned int path_l
|
||||||
if ((e = r3_node_find_edge_str(n, path, path_len))) {
|
if ((e = r3_node_find_edge_str(n, path, path_len))) {
|
||||||
restlen = path_len - e->pattern.len;
|
restlen = path_len - e->pattern.len;
|
||||||
if (!restlen) {
|
if (!restlen) {
|
||||||
|
if (is_end) {
|
||||||
return e->child && e->child->endpoint ? e->child : NULL;
|
return e->child && e->child->endpoint ? e->child : NULL;
|
||||||
}
|
}
|
||||||
return r3_tree_matchl(e->child, path + e->pattern.len, restlen, entry);
|
|
||||||
|
R3Node *n = r3_tree_matchl_base(e->child, path + e->pattern.len, restlen, entry, 1);
|
||||||
|
if (n == NULL) {
|
||||||
|
return e->child && e->child->endpoint ? e->child : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
return r3_tree_matchl_base(e->child, path + e->pattern.len, restlen, entry, is_end);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function matches the URL path and return the left node
|
||||||
|
*
|
||||||
|
* r3_tree_matchl returns NULL when the path does not match. returns *node when the path matches.
|
||||||
|
*
|
||||||
|
* @param node n the root of the tree
|
||||||
|
* @param char* path the URL path to dispatch
|
||||||
|
* @param int path_len the length of the URL path.
|
||||||
|
* @param match_entry* entry match_entry is used for saving the captured dynamic strings from pcre result.
|
||||||
|
*/
|
||||||
|
R3Node * r3_tree_matchl(const R3Node * n, const char * path,
|
||||||
|
unsigned int path_len, match_entry * entry) {
|
||||||
|
return r3_tree_matchl_base(n, path, path_len, entry, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
R3Route * r3_tree_match_route(const R3Node *tree, match_entry * entry) {
|
R3Route * r3_tree_match_route(const R3Node *tree, match_entry * entry) {
|
||||||
R3Node *n;
|
R3Node *n;
|
||||||
|
|
|
@ -23,6 +23,5 @@ add_r3_test(check_http_scheme check_http_scheme.c)
|
||||||
add_r3_test(check_remote_addr check_remote_addr.c)
|
add_r3_test(check_remote_addr check_remote_addr.c)
|
||||||
add_r3_test(check_routes2 check_routes2.c)
|
add_r3_test(check_routes2 check_routes2.c)
|
||||||
|
|
||||||
|
|
||||||
add_executable(bench bench.c)
|
add_executable(bench bench.c)
|
||||||
target_link_libraries(bench r3)
|
target_link_libraries(bench r3)
|
||||||
|
|
|
@ -24,12 +24,10 @@ START_TEST (greedy_pattern)
|
||||||
ck_assert(matched_route != NULL);
|
ck_assert(matched_route != NULL);
|
||||||
ck_assert(matched_route->data == &uri0);
|
ck_assert(matched_route->data == &uri0);
|
||||||
|
|
||||||
// fixme: should match
|
entry = match_entry_create("/foo");
|
||||||
|
matched_route = r3_tree_match_route(n, entry);
|
||||||
// entry = match_entry_create("/foo");
|
ck_assert(matched_route != NULL);
|
||||||
// matched_route = r3_tree_match_route(n, entry);
|
ck_assert(matched_route->data == &uri0);
|
||||||
// ck_assert(matched_route != NULL);
|
|
||||||
// ck_assert(matched_route->data == &uri0);
|
|
||||||
|
|
||||||
entry = match_entry_create("/foo/");
|
entry = match_entry_create("/foo/");
|
||||||
matched_route = r3_tree_match_route(n, entry);
|
matched_route = r3_tree_match_route(n, entry);
|
||||||
|
@ -62,4 +60,3 @@ int main (int argc, char *argv[]) {
|
||||||
srunner_free(runner);
|
srunner_free(runner);
|
||||||
return number_failed;
|
return number_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue