diff options
author | Jan Kneschke <jan@kneschke.de> | 2005-08-08 17:25:55 +0000 |
---|---|---|
committer | Jan Kneschke <jan@kneschke.de> | 2005-08-08 17:25:55 +0000 |
commit | 360aba360f5bb6c8db7f98717d67c08448b7a111 (patch) | |
tree | a1b3ccf8ee9658351357ca54a62997aff71aca09 /src | |
parent | 8b07d57d66b28931a99ae6358a1644ab171cd7f1 (diff) | |
download | lighttpd-git-360aba360f5bb6c8db7f98717d67c08448b7a111.tar.gz |
allow _ in env. and var. and optimized matching of conditions
git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-merge-1.4.x@529 152afb58-edef-0310-8abb-c4023f1b3aa9
Diffstat (limited to 'src')
-rw-r--r-- | src/configfile-glue.c | 21 | ||||
-rw-r--r-- | src/configfile.c | 16 | ||||
-rw-r--r-- | src/configparser.y | 112 | ||||
-rw-r--r-- | src/connections.c | 1 | ||||
-rw-r--r-- | src/mod_rewrite.c | 2 | ||||
-rw-r--r-- | src/network.c | 2 | ||||
-rw-r--r-- | src/plugin.h | 2 | ||||
-rw-r--r-- | src/response.c | 13 |
8 files changed, 100 insertions, 69 deletions
diff --git a/src/configfile-glue.c b/src/configfile-glue.c index 067ac05c..00e28ea8 100644 --- a/src/configfile-glue.c +++ b/src/configfile-glue.c @@ -174,18 +174,11 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat } } - /* - * OPTIMIZE - * - * - replace all is_equal be simple == to an enum - * - */ - /* pass the rules */ l = srv->empty_string; - if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPhost"))) { + if (COMP_HTTP_HOST == dc->comp) { l = con->uri.authority; #if 0 /* FIXME: get this working again */ @@ -215,7 +208,7 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat break; } } - } else if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPremoteip"))) { + } else if (COMP_HTTP_REMOTEIP == dc->comp) { char *nm_slash; /* handle remoteip limitations * @@ -290,22 +283,22 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat buffer_copy_string(srv->cond_check_buf, s); } #endif - } else if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPurl"))) { + } else if (COMP_HTTP_URL == dc->comp) { l = con->uri.path; - } else if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("SERVERsocket"))) { + } else if (COMP_SERVER_SOCKET == dc->comp) { l = srv_sock->srv_token; - } else if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPreferer"))) { + } else if (COMP_HTTP_REFERER == dc->comp) { data_string *ds; if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) { l = ds->value; } - } else if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPcookie"))) { + } else if (COMP_HTTP_COOKIE == dc->comp) { data_string *ds; if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) { l = ds->value; } - } else if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPuseragent"))) { + } else if (COMP_HTTP_USERAGENT == dc->comp) { data_string *ds; if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "User-Agent"))) { l = ds->value; diff --git a/src/configfile.c b/src/configfile.c index 4c53cfbf..0597eb3a 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -266,7 +266,7 @@ int config_setup_connection(server *srv, connection *con) { return 0; } -int config_patch_connection(server *srv, connection *con, const char *stage, size_t stage_len) { +int config_patch_connection(server *srv, connection *con, comp_key_t comp) { size_t i, j; /* skip the first, the global context */ @@ -275,7 +275,7 @@ int config_patch_connection(server *srv, connection *con, const char *stage, siz specific_config *s = srv->config_storage[i]; /* not our stage */ - if (!buffer_is_equal_string(dc->comp_key, stage, stage_len)) continue; + if (comp != dc->comp) continue; /* condition didn't match */ if (!config_check_cond(srv, con, dc)) continue; @@ -739,6 +739,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * for (i = 0; t->input[t->offset + i] && (isalnum((unsigned char)t->input[t->offset + i]) || t->input[t->offset + i] == '.' || + t->input[t->offset + i] == '_' || /* for env.* */ t->input[t->offset + i] == '-' ); i++); @@ -838,19 +839,12 @@ static void context_init(server *srv, config_t *context) { context->srv = srv; context->ok = 1; context->configs_stack = array_init(); + context->configs_stack->is_weakref = 1; context->basedir = buffer_init(); } static void context_free(config_t *context) { - size_t i; - array *a = context->configs_stack; - - /* don't free elements */ - for (i = 0; i < a->size; i++) { - a->data[i] = NULL; - } - array_free(a); - + array_free(context->configs_stack); buffer_free(context->basedir); } diff --git a/src/configparser.y b/src/configparser.y index ad00f233..23e19140 100644 --- a/src/configparser.y +++ b/src/configparser.y @@ -17,6 +17,7 @@ static void configparser_push(config_t *ctx, data_config *dc, int isnew) { assert(dc->context_ndx > ctx->current->context_ndx); array_insert_unique(ctx->all_configs, (data_unset *)dc); dc->parent = ctx->current; + array_insert_unique(dc->parent->childs, (data_unset *)dc); } array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current); ctx->current = dc; @@ -28,30 +29,42 @@ static data_config *configparser_pop(config_t *ctx) { return old; } -static const data_unset *configparser_get_variable(config_t *ctx, buffer *key) { - data_unset *ds, *result; - data_config *dc; +/* return a copied variable */ +static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) { + if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) { + char *env; + + if (NULL != (env = getenv(key->ptr + 4))) { + data_string *ds; + ds = data_string_init(); + buffer_append_string(ds->value, env); + return (data_unset *)ds; + } + + fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4); + ctx->ok = 0; + + return NULL; + } else { + data_unset *du; + data_config *dc; - result = NULL; #if 0 - fprintf(stderr, "get var %s\n", key->ptr); + fprintf(stderr, "get var %s\n", key->ptr); #endif - for (dc = ctx->current; dc && !result; dc = dc->parent) { + for (dc = ctx->current; dc; dc = dc->parent) { #if 0 - fprintf(stderr, "get var on block: %s\n", dc->key->ptr); - array_print(dc->value, 0); + fprintf(stderr, "get var on block: %s\n", dc->key->ptr); + array_print(dc->value, 0); #endif - ds = array_get_element(dc->value, key->ptr); - if (NULL != ds) { - result = ds; - break; + if (NULL != (du = array_get_element(dc->value, key->ptr))) { + return du->copy(du); + } } - } - if (NULL == result) { fprintf(stderr, "Undefined config variable: %s\n", key->ptr); ctx->ok = 0; + return NULL; } - return result; } /* op1 is to be eat/return by this function, op1->key is not cared @@ -161,7 +174,6 @@ varline ::= key(A) ASSIGN expression(B). { varline ::= key(A) APPEND expression(B). { array *vars = ctx->current->value; - const data_unset *var; data_unset *du; if (NULL != (du = array_get_element(vars, A->ptr))) { @@ -169,9 +181,8 @@ varline ::= key(A) APPEND expression(B). { du = configparser_merge_data(ctx, du, B); buffer_copy_string_buffer(du->key, A); array_replace(vars, du); - } else if (NULL != (var = configparser_get_variable(ctx, A))) { - du = var->copy(var); - du = configparser_merge_data(ctx, du->copy(du), B); + } else if (NULL != (du = configparser_get_variable(ctx, A))) { + du = configparser_merge_data(ctx, du, B); buffer_copy_string_buffer(du->key, A); array_insert_unique(ctx->current->value, du); } else { @@ -210,11 +221,8 @@ expression(A) ::= value(B). { } value(A) ::= key(B). { - const data_unset *var = configparser_get_variable(ctx, B); - if (var) { - A = var->copy(var); - } - else { + A = configparser_get_variable(ctx, B); + if (!A) { /* make a dummy so it won't crash */ A = (data_unset *)data_string_init(); } @@ -317,48 +325,81 @@ condline(A) ::= context LCURLY metalines RCURLY. { context ::= DOLLAR SRVVARNAME(B) LBRACKET STRING(C) RBRACKET cond(E) expression(D). { data_config *dc; - buffer *b, *rvalue; + buffer *b, *rvalue, *op; if (ctx->ok && D->type != TYPE_STRING) { fprintf(stderr, "rvalue must be string"); ctx->ok = 0; } - b = buffer_init(); - buffer_copy_string_buffer(b, ctx->current->key); - buffer_append_string(b, "/"); - buffer_append_string_buffer(b, B); - buffer_append_string_buffer(b, C); switch(E) { case CONFIG_COND_NE: - buffer_append_string_len(b, CONST_STR_LEN("!=")); + op = buffer_init_string("!="); break; case CONFIG_COND_EQ: - buffer_append_string_len(b, CONST_STR_LEN("==")); + op = buffer_init_string("=="); break; case CONFIG_COND_NOMATCH: - buffer_append_string_len(b, CONST_STR_LEN("!~")); + op = buffer_init_string("!~"); break; case CONFIG_COND_MATCH: - buffer_append_string_len(b, CONST_STR_LEN("=~")); + op = buffer_init_string("=~"); break; default: - buffer_append_string_len(b, CONST_STR_LEN("??")); + assert(0); break; } + + b = buffer_init(); + buffer_copy_string_buffer(b, ctx->current->key); + buffer_append_string(b, "/"); + buffer_append_string_buffer(b, B); + buffer_append_string_buffer(b, C); + buffer_append_string_buffer(b, op); rvalue = ((data_string*)D)->value; buffer_append_string_buffer(b, rvalue); if (NULL != (dc = (data_config *)array_get_element(ctx->all_configs, b->ptr))) { configparser_push(ctx, dc, 0); } else { + struct { + comp_key_t comp; + char *comp_key; + size_t len; + } comps[] = { + { COMP_SERVER_SOCKET, CONST_STR_LEN("SERVER[\"socket\"]" ) }, + { COMP_HTTP_URL, CONST_STR_LEN("HTTP[\"url\"]" ) }, + { COMP_HTTP_HOST, CONST_STR_LEN("HTTP[\"host\"]" ) }, + { COMP_HTTP_REFERER, CONST_STR_LEN("HTTP[\"referer\"]" ) }, + { COMP_HTTP_USERAGENT, CONST_STR_LEN("HTTP[\"useragent\"]" ) }, + { COMP_HTTP_COOKIE, CONST_STR_LEN("HTTP[\"cookie\"]" ) }, + { COMP_HTTP_REMOTEIP, CONST_STR_LEN("HTTP[\"remoteip\"]" ) }, + { COMP_UNSET, NULL, 0 }, + }; + size_t i; + dc = data_config_init(); buffer_copy_string_buffer(dc->key, b); + buffer_copy_string_buffer(dc->op, op); buffer_copy_string_buffer(dc->comp_key, B); + buffer_append_string_len(dc->comp_key, CONST_STR_LEN("[\"")); buffer_append_string_buffer(dc->comp_key, C); + buffer_append_string_len(dc->comp_key, CONST_STR_LEN("\"]")); dc->cond = E; + for (i = 0; comps[i].comp_key; i ++) { + if (buffer_is_equal_string( + dc->comp_key, comps[i].comp_key, comps[i].len)) { + dc->comp = comps[i].comp; + break; + } + } + if (COMP_UNSET == dc->comp) { + fprintf(stderr, "error comp_key %s", dc->comp_key->ptr); + ctx->ok = 0; + } + switch(E) { case CONFIG_COND_NE: case CONFIG_COND_EQ: @@ -408,6 +449,7 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET STRING(C) RBRACKET cond(E) expression( } buffer_free(b); + buffer_free(op); buffer_free(B); B = NULL; buffer_free(C); diff --git a/src/connections.c b/src/connections.c index 96083485..1842f3c6 100644 --- a/src/connections.c +++ b/src/connections.c @@ -653,6 +653,7 @@ void connections_free(server *srv) { CLEAN(error_handler); #undef CLEAN free(con->plugin_ctx); + free(con->cond_results_cache); free(con); } diff --git a/src/mod_rewrite.c b/src/mod_rewrite.c index bf1b8446..345f6f6c 100644 --- a/src/mod_rewrite.c +++ b/src/mod_rewrite.c @@ -276,7 +276,7 @@ static int mod_rewrite_patch_connection(server *srv, connection *con, plugin_dat data_config *dc = (data_config *)srv->config_context->data[i]; s = p->config_storage[i]; - if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPurl"))) continue; + if (COMP_HTTP_URL == dc->comp) continue; /* condition didn't match */ if (!config_check_cond(srv, con, dc)) continue; diff --git a/src/network.c b/src/network.c index 2d475afa..c40077d4 100644 --- a/src/network.c +++ b/src/network.c @@ -386,7 +386,7 @@ int network_init(server *srv) { specific_config *s = srv->config_storage[i]; /* not our stage */ - if (!buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("SERVERsocket"))) continue; + if (COMP_SERVER_SOCKET != dc->comp) continue; if (dc->cond != CONFIG_COND_EQ) { log_error_write(srv, __FILE__, __LINE__, "s", "only == is allowed for $SERVER[\"socket\"]."); diff --git a/src/plugin.h b/src/plugin.h index 8a141770..dad01424 100644 --- a/src/plugin.h +++ b/src/plugin.h @@ -87,7 +87,7 @@ handler_t plugins_call_cleanup(server *srv); int config_insert_values_global(server *srv, array *ca, const config_values_t *cv); int config_insert_values_internal(server *srv, array *ca, const config_values_t *cv); int config_setup_connection(server *srv, connection *con); -int config_patch_connection(server *srv, connection *con, const char *stage, size_t stage_len); +int config_patch_connection(server *srv, connection *con, comp_key_t comp); int config_check_cond(server *srv, connection *con, data_config *dc); #endif diff --git a/src/response.c b/src/response.c index aee79e55..f15bf769 100644 --- a/src/response.c +++ b/src/response.c @@ -974,7 +974,8 @@ handler_t http_response_prepare(server *srv, connection *con) { if (con->mode == DIRECT && con->physical.path->used == 0) { char *qstr; - config_patch_connection(srv, con, CONST_STR_LEN("SERVERsocket")); /* SERVERsocket */ + config_patch_connection(srv, con, COMP_SERVER_SOCKET); /* SERVERsocket */ + config_patch_connection(srv, con, COMP_HTTP_REMOTEIP); /* Client-IP */ /** * prepare strings @@ -1001,10 +1002,10 @@ handler_t http_response_prepare(server *srv, connection *con) { buffer_copy_string(con->uri.scheme, con->conf.is_ssl ? "https" : "http"); buffer_copy_string_buffer(con->uri.authority, con->request.http_host); - config_patch_connection(srv, con, CONST_STR_LEN("HTTPhost")); /* Host: */ - config_patch_connection(srv, con, CONST_STR_LEN("HTTPreferer")); /* Referer: */ - config_patch_connection(srv, con, CONST_STR_LEN("HTTPuseragent")); /* User-Agent: */ - config_patch_connection(srv, con, CONST_STR_LEN("HTTPcookie")); /* Cookie: */ + config_patch_connection(srv, con, COMP_HTTP_HOST); /* Host: */ + config_patch_connection(srv, con, COMP_HTTP_REFERER); /* Referer: */ + config_patch_connection(srv, con, COMP_HTTP_USERAGENT); /* User-Agent: */ + config_patch_connection(srv, con, COMP_HTTP_COOKIE); /* Cookie: */ /** extract query string from request.uri */ if (NULL != (qstr = strchr(con->request.uri->ptr, '?'))) { @@ -1077,7 +1078,7 @@ handler_t http_response_prepare(server *srv, connection *con) { * */ - config_patch_connection(srv, con, CONST_STR_LEN("HTTPurl")); /* HTTPurl */ + config_patch_connection(srv, con, COMP_HTTP_URL); /* HTTPurl */ switch(r = plugins_call_handle_uri_clean(srv, con)) { case HANDLER_GO_ON: |