summaryrefslogtreecommitdiff
path: root/src/mod_redirect.c
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2018-01-10 01:39:05 -0500
committerGlenn Strauss <gstrauss@gluelogic.com>2018-01-10 01:39:05 -0500
commitcb371557e56c281d311667eba88f66c1c81213dc (patch)
tree01e635c0423278921c34af780c35cbdadebe05e8 /src/mod_redirect.c
parenta5a2654bd4cbebbeb9d52e6440155bb0a53efa29 (diff)
downloadlighttpd-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.c63
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);