diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2018-01-10 01:39:05 -0500 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2018-01-10 01:39:05 -0500 |
commit | cb371557e56c281d311667eba88f66c1c81213dc (patch) | |
tree | 01e635c0423278921c34af780c35cbdadebe05e8 /src/mod_redirect.c | |
parent | a5a2654bd4cbebbeb9d52e6440155bb0a53efa29 (diff) | |
download | lighttpd-git-cb371557e56c281d311667eba88f66c1c81213dc.tar.gz |
[core] merge redirect/rewrite pattern substitution
merge redirect/rewrite pattern substitution function (share code)
Diffstat (limited to 'src/mod_redirect.c')
-rw-r--r-- | src/mod_redirect.c | 63 |
1 files changed, 7 insertions, 56 deletions
diff --git a/src/mod_redirect.c b/src/mod_redirect.c index 4812e90d..830812f2 100644 --- a/src/mod_redirect.c +++ b/src/mod_redirect.c @@ -20,7 +20,6 @@ typedef struct { typedef struct { PLUGIN_DATA; - buffer *match_buf; buffer *location; plugin_config **config_storage; @@ -33,7 +32,6 @@ INIT_FUNC(mod_redirect_init) { p = calloc(1, sizeof(*p)); - p->match_buf = buffer_init(); p->location = buffer_init(); return p; @@ -59,7 +57,6 @@ FREE_FUNC(mod_redirect_free) { } - buffer_free(p->match_buf); buffer_free(p->location); free(p); @@ -165,6 +162,7 @@ static int mod_redirect_patch_connection(server *srv, connection *con, plugin_da static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_data) { #ifdef HAVE_PCRE_H plugin_data *p = p_data; + cond_cache_t *cache; size_t i; /* @@ -175,78 +173,31 @@ static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_ */ mod_redirect_patch_connection(srv, con, p); - - buffer_copy_buffer(p->match_buf, con->request.uri); + cache = p->conf.context ? &con->cond_cache[p->conf.context->context_ndx] : NULL; for (i = 0; i < p->conf.redirect->used; i++) { - pcre *match; - pcre_extra *extra; - const char *pattern; - size_t pattern_len; - int n; pcre_keyvalue *kv = p->conf.redirect->kv[i]; # define N 10 int ovec[N * 3]; + int n = pcre_exec(kv->key, kv->key_extra, CONST_BUF_LEN(con->request.uri), 0, 0, ovec, 3 * N); - match = kv->key; - extra = kv->key_extra; - pattern = kv->value->ptr; - pattern_len = buffer_string_length(kv->value); - - if ((n = pcre_exec(match, extra, CONST_BUF_LEN(p->match_buf), 0, 0, ovec, 3 * N)) < 0) { + if (n < 0) { if (n != PCRE_ERROR_NOMATCH) { log_error_write(srv, __FILE__, __LINE__, "sd", "execution error while matching: ", n); return HANDLER_ERROR; } - } else if (0 == pattern_len) { + } else if (0 == buffer_string_length(kv->value)) { /* short-circuit if blank replacement pattern * (do not attempt to match against remaining redirect rules) */ return HANDLER_GO_ON; } else { const char **list; - size_t start; - size_t k; /* it matched */ - pcre_get_substring_list(p->match_buf->ptr, ovec, n, &list); - - /* search for $[0-9] */ - - buffer_reset(p->location); - - start = 0; - for (k = 0; k + 1 < pattern_len; k++) { - if (pattern[k] == '$' || pattern[k] == '%') { - /* got one */ - - size_t num = pattern[k + 1] - '0'; - - buffer_append_string_len(p->location, pattern + start, k - start); - - if (!isdigit((unsigned char)pattern[k + 1])) { - /* enable escape: "%%" => "%", "%a" => "%a", "$$" => "$" */ - buffer_append_string_len(p->location, pattern+k, pattern[k] == pattern[k+1] ? 1 : 2); - } else if (pattern[k] == '$') { - /* n is always > 0 */ - if (num < (size_t)n) { - buffer_append_string(p->location, list[num]); - } - } else if (p->conf.context == NULL) { - /* we have no context, we are global */ - log_error_write(srv, __FILE__, __LINE__, "sb", - "used a rewrite containing a %[0-9]+ in the global scope, ignored:", - kv->value); - } else { - config_append_cond_match_buffer(con, p->conf.context, p->location, num); - } - - k++; - start = k + 1; - } - } + pcre_get_substring_list(con->request.uri->ptr, ovec, n, &list); - buffer_append_string_len(p->location, pattern + start, pattern_len - start); + pcre_keyvalue_buffer_subst(p->location, kv->value, list, n, cache); pcre_free(list); |