diff options
author | Jan Kneschke <jan@kneschke.de> | 2005-07-23 20:58:46 +0000 |
---|---|---|
committer | Jan Kneschke <jan@kneschke.de> | 2005-07-23 20:58:46 +0000 |
commit | 23300a91c2bba000fb3e094a99fd48414a047138 (patch) | |
tree | 8d2b08e15d8db704e5aa3066f5e437e9a3405e0a /src/mod_rewrite.c | |
parent | 4853c620e0c396922e4649df719c750daadcbdaf (diff) | |
download | lighttpd-git-23300a91c2bba000fb3e094a99fd48414a047138.tar.gz |
added url.rewrite-once and url.rewrite-repeat and mapped the old options both to url.rewrite-once
if the user really wants url.rewrite-repeat he has to use it expecitly.
Added detection for endless loops
git-svn-id: svn+ssh://svn.lighttpd.net/lighttpd/branches/lighttpd-1.3.x@471 152afb58-edef-0310-8abb-c4023f1b3aa9
Diffstat (limited to 'src/mod_rewrite.c')
-rw-r--r-- | src/mod_rewrite.c | 159 |
1 files changed, 78 insertions, 81 deletions
diff --git a/src/mod_rewrite.c b/src/mod_rewrite.c index 868abb5f..1c9916b7 100644 --- a/src/mod_rewrite.c +++ b/src/mod_rewrite.c @@ -19,7 +19,7 @@ typedef struct { buffer *value; - int final; + int once; } rewrite_rule; typedef struct { @@ -35,6 +35,7 @@ typedef struct { typedef struct { enum { REWRITE_STATE_UNSET, REWRITE_STATE_FINISHED} state; + int loops; } handler_ctx; typedef struct { @@ -52,6 +53,7 @@ static handler_ctx * handler_ctx_init() { hctx = calloc(1, sizeof(*hctx)); hctx->state = REWRITE_STATE_UNSET; + hctx->loops = 0; return hctx; } @@ -68,7 +70,7 @@ rewrite_rule_buffer *rewrite_rule_buffer_init(void) { return kvb; } -int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int final) { +int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int once) { #ifdef HAVE_PCRE_H size_t i; const char *errptr; @@ -103,7 +105,7 @@ int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *va kvb->ptr[kvb->used]->value = buffer_init(); buffer_copy_string_buffer(kvb->ptr[kvb->used]->value, value); - kvb->ptr[kvb->used]->final = final; + kvb->ptr[kvb->used]->once = once; kvb->used++; @@ -111,7 +113,7 @@ int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *va #else UNUSED(kvb); UNUSED(value); - UNUSED(final); + UNUSED(once); UNUSED(key); return -1; @@ -169,15 +171,67 @@ FREE_FUNC(mod_rewrite_free) { return HANDLER_GO_ON; } +static int parse_config_entry(server *srv, plugin_config *s, array *ca, const char *option, int once) { + data_unset *du; + + if (NULL != (du = array_get_element(ca, option))) { + data_array *da = (data_array *)du; + size_t j; + + if (du->type != TYPE_ARRAY) { + log_error_write(srv, __FILE__, __LINE__, "sss", + "unexpected type for key: ", option, "array of strings"); + + return HANDLER_ERROR; + } + + da = (data_array *)du; + + for (j = 0; j < da->value->used; j++) { + if (da->value->data[j]->type != TYPE_STRING) { + log_error_write(srv, __FILE__, __LINE__, "sssbs", + "unexpected type for key: ", + option, + "[", da->value->data[j]->key, "](string)"); + + return HANDLER_ERROR; + } + + if (0 != rewrite_rule_buffer_append(s->rewrite, + ((data_string *)(da->value->data[j]))->key, + ((data_string *)(da->value->data[j]))->value, + once)) { +#ifdef HAVE_PCRE_H + log_error_write(srv, __FILE__, __LINE__, "sb", + "pcre-compile failed for", da->value->data[j]->key); +#else + log_error_write(srv, __FILE__, __LINE__, "s", + "pcre support is missing, please install libpcre and the headers"); +#endif + } + } + } + + return 0; +} + SETDEFAULTS_FUNC(mod_rewrite_set_defaults) { plugin_data *p = p_d; - data_unset *du; size_t i = 0; config_values_t cv[] = { - { "url.rewrite", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ - { "url.rewrite-final", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ - { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } + { "url.rewrite-repeat", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ + { "url.rewrite-once", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ + + /* old names, still supported + * + * url.rewrite remapped to url.rewrite-once + * url.rewrite-final is url.rewrite-once + * + */ + { "url.rewrite", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ + { "url.rewrite-final", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 3 */ + { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } }; if (!p) return HANDLER_ERROR; @@ -187,15 +241,14 @@ SETDEFAULTS_FUNC(mod_rewrite_set_defaults) { for (i = 0; i < srv->config_context->used; i++) { plugin_config *s; - size_t j; array *ca; - data_array *da = (data_array *)du; s = malloc(sizeof(plugin_config)); s->rewrite = rewrite_rule_buffer_init(); cv[0].destination = s->rewrite; cv[1].destination = s->rewrite; + cv[2].destination = s->rewrite; p->config_storage[i] = s; ca = ((data_config *)srv->config_context->data[i])->value; @@ -204,76 +257,10 @@ SETDEFAULTS_FUNC(mod_rewrite_set_defaults) { return HANDLER_ERROR; } - if (NULL != (du = array_get_element(ca, "url.rewrite"))) { - if (du->type != TYPE_ARRAY) { - log_error_write(srv, __FILE__, __LINE__, "sss", - "unexpected type for key: ", "url.rewrite", "array of strings"); - - return HANDLER_ERROR; - } - - da = (data_array *)du; - - for (j = 0; j < da->value->used; j++) { - if (da->value->data[j]->type != TYPE_STRING) { - log_error_write(srv, __FILE__, __LINE__, "sssbs", - "unexpected type for key: ", - "url.rewrite", - "[", da->value->data[j]->key, "](string)"); - - return HANDLER_ERROR; - } - - if (0 != rewrite_rule_buffer_append(s->rewrite, - ((data_string *)(da->value->data[j]))->key, - ((data_string *)(da->value->data[j]))->value, - 0)) { -#ifdef HAVE_PCRE_H - log_error_write(srv, __FILE__, __LINE__, "sb", - "pcre-compile failed for", da->value->data[j]->key); -#else - log_error_write(srv, __FILE__, __LINE__, "s", - "pcre support is missing, please install libpcre and the headers"); -#endif - } - } - } - - if (NULL != (du = array_get_element(ca, "url.rewrite-final"))) { - if (du->type != TYPE_ARRAY) { - log_error_write(srv, __FILE__, __LINE__, "sss", - "unexpected type for key: ", "url.rewrite", "array of strings"); - - return HANDLER_ERROR; - } - - da = (data_array *)du; - - for (j = 0; j < da->value->used; j++) { - if (da->value->data[j]->type != TYPE_STRING) { - log_error_write(srv, __FILE__, __LINE__, "sssbs", - "unexpected type for key: ", - "url.rewrite", - "[", da->value->data[j]->key, "](string)"); - - return HANDLER_ERROR; - } - - if (0 != rewrite_rule_buffer_append(s->rewrite, - ((data_string *)(da->value->data[j]))->key, - ((data_string *)(da->value->data[j]))->value, - 1)) { - -#ifdef HAVE_PCRE_H - log_error_write(srv, __FILE__, __LINE__, "sb", - "pcre-compile failed for", da->value->data[j]->key); -#else - log_error_write(srv, __FILE__, __LINE__, "s", - "pcre support is missing, please install libpcre and the headers"); -#endif - } - } - } + parse_config_entry(srv, s, ca, "url.rewrite-once", 1); + parse_config_entry(srv, s, ca, "url.rewrite-final", 1); + parse_config_entry(srv, s, ca, "url.rewrite", 1); + parse_config_entry(srv, s, ca, "url.rewrite-repeat", 0); } return HANDLER_GO_ON; @@ -299,6 +286,10 @@ static int mod_rewrite_patch_connection(server *srv, connection *con, plugin_dat if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite"))) { p->conf.rewrite = s->rewrite; + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-once"))) { + p->conf.rewrite = s->rewrite; + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-repeat"))) { + p->conf.rewrite = s->rewrite; } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-final"))) { p->conf.rewrite = s->rewrite; } @@ -348,6 +339,12 @@ URIHANDLER_FUNC(mod_rewrite_uri_handler) { if (con->plugin_ctx[p->id]) { hctx = con->plugin_ctx[p->id]; + if (hctx->loops++ > 100) { + log_error_write(srv, __FILE__, __LINE__, "s", "ENDLESS LOOP IN rewrite-rule DETECTED ... aborting request, perhaps you want to use url.rewrite instead of url.rewrite-repeat"); + + return HANDLER_ERROR; + } + if (hctx->state == REWRITE_STATE_FINISHED) return HANDLER_GO_ON; } @@ -421,7 +418,7 @@ URIHANDLER_FUNC(mod_rewrite_uri_handler) { con->plugin_ctx[p->id] = hctx; - if (rule->final) hctx->state = REWRITE_STATE_FINISHED; + if (rule->once) hctx->state = REWRITE_STATE_FINISHED; return HANDLER_COMEBACK; } |