Browse Source

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://svn.lighttpd.net/lighttpd/branches/lighttpd-1.3.x@471 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/heads/lighttpd-1.3.x
Jan Kneschke 17 years ago
parent
commit
6215997b8d
  1. 159
      src/mod_rewrite.c

159
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;
}

Loading…
Cancel
Save