From 2ac2911b9aa253e26a660241bbe37cdbcdd8d050 Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Fri, 20 Jan 2017 09:59:21 -0500 Subject: [PATCH] [core] config match w/ arbitrary HTTP request hdrs (fixes #1556) x-ref: "Allow matching against any arbitrary HTTP header in the configuration file regexps" https://redmine.lighttpd.net/issues/1556 --- src/array.h | 6 ++++-- src/configfile-glue.c | 32 ++------------------------------ src/configparser.y | 24 +++++++++++++++++++----- src/data_config.c | 5 +++++ src/response.c | 1 + 5 files changed, 31 insertions(+), 37 deletions(-) diff --git a/src/array.h b/src/array.h index e2603f3c..9225e53c 100644 --- a/src/array.h +++ b/src/array.h @@ -76,14 +76,15 @@ typedef enum { COMP_SERVER_SOCKET, COMP_HTTP_URL, COMP_HTTP_HOST, - COMP_HTTP_REFERER, + COMP_HTTP_REFERER, /*(subsumed by COMP_HTTP_REQUEST_HEADER)*/ COMP_HTTP_USER_AGENT, COMP_HTTP_LANGUAGE, - COMP_HTTP_COOKIE, + COMP_HTTP_COOKIE, /*(subsumed by COMP_HTTP_REQUEST_HEADER)*/ COMP_HTTP_REMOTE_IP, COMP_HTTP_QUERY_STRING, COMP_HTTP_SCHEME, COMP_HTTP_REQUEST_METHOD, + COMP_HTTP_REQUEST_HEADER, COMP_LAST_ELEMENT } comp_key_t; @@ -101,6 +102,7 @@ struct data_config { array *value; + buffer *comp_tag; buffer *comp_key; comp_key_t comp; diff --git a/src/configfile-glue.c b/src/configfile-glue.c index ec9e4f7f..fab447e4 100644 --- a/src/configfile-glue.c +++ b/src/configfile-glue.c @@ -489,28 +489,9 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat l = srv_sock->srv_token; break; - case COMP_HTTP_REFERER: { + case COMP_HTTP_REQUEST_HEADER: { data_string *ds; - - if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) { - l = ds->value; - } else { - l = srv->empty_string; - } - break; - } - case COMP_HTTP_COOKIE: { - data_string *ds; - if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) { - l = ds->value; - } else { - l = srv->empty_string; - } - break; - } - case COMP_HTTP_USER_AGENT: { - data_string *ds; - if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "User-Agent"))) { + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, dc->comp_tag->ptr))) { l = ds->value; } else { l = srv->empty_string; @@ -528,15 +509,6 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat break; } - case COMP_HTTP_LANGUAGE: { - data_string *ds; - if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Accept-Language"))) { - l = ds->value; - } else { - l = srv->empty_string; - } - break; - } default: return COND_RESULT_FALSE; } diff --git a/src/configparser.y b/src/configparser.y index cdffd043..9def054f 100644 --- a/src/configparser.y +++ b/src/configparser.y @@ -552,11 +552,11 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio { 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_REQUEST_HEADER,CONST_STR_LEN("HTTP[\"referer\"]" ) }, { COMP_HTTP_USER_AGENT, CONST_STR_LEN("HTTP[\"useragent\"]" ) }, - { COMP_HTTP_USER_AGENT, CONST_STR_LEN("HTTP[\"user-agent\"]" ) }, + { COMP_HTTP_REQUEST_HEADER,CONST_STR_LEN("HTTP[\"user-agent\"]" ) }, { COMP_HTTP_LANGUAGE, CONST_STR_LEN("HTTP[\"language\"]" ) }, - { COMP_HTTP_COOKIE, CONST_STR_LEN("HTTP[\"cookie\"]" ) }, + { COMP_HTTP_REQUEST_HEADER,CONST_STR_LEN("HTTP[\"cookie\"]" ) }, { COMP_HTTP_REMOTE_IP, CONST_STR_LEN("HTTP[\"remoteip\"]" ) }, { COMP_HTTP_REMOTE_IP, CONST_STR_LEN("HTTP[\"remote-ip\"]" ) }, { COMP_HTTP_QUERY_STRING, CONST_STR_LEN("HTTP[\"querystring\"]") }, @@ -571,6 +571,7 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio buffer_copy_buffer(dc->key, b); buffer_copy_buffer(dc->op, op); + buffer_copy_buffer(dc->comp_tag, C); buffer_copy_buffer(dc->comp_key, B); buffer_append_string_len(dc->comp_key, CONST_STR_LEN("[\"")); buffer_append_string_buffer(dc->comp_key, C); @@ -585,8 +586,21 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio } } if (COMP_UNSET == dc->comp) { - fprintf(stderr, "error comp_key %s", dc->comp_key->ptr); - ctx->ok = 0; + if (buffer_is_equal_string(B, CONST_STR_LEN("REQUEST_HEADER"))) { + dc->comp = COMP_HTTP_REQUEST_HEADER; + } + else { + fprintf(stderr, "error comp_key %s", dc->comp_key->ptr); + ctx->ok = 0; + } + } + else if (COMP_HTTP_LANGUAGE == dc->comp) { + dc->comp = COMP_HTTP_REQUEST_HEADER; + buffer_copy_string_len(dc->comp_tag, CONST_STR_LEN("Accept-Language")); + } + else if (COMP_HTTP_USER_AGENT == dc->comp) { + dc->comp = COMP_HTTP_REQUEST_HEADER; + buffer_copy_string_len(dc->comp_tag, CONST_STR_LEN("User-Agent")); } else if (COMP_HTTP_REMOTE_IP == dc->comp && (dc->cond == CONFIG_COND_EQ || dc->cond == CONFIG_COND_NE)) { diff --git a/src/data_config.c b/src/data_config.c index 30c32bd2..99ae7307 100644 --- a/src/data_config.c +++ b/src/data_config.c @@ -10,7 +10,9 @@ static data_unset *data_config_copy(const data_unset *s) { data_config *src = (data_config *)s; data_config *ds = data_config_init(); + ds->comp = src->comp; buffer_copy_buffer(ds->key, src->key); + buffer_copy_buffer(ds->comp_tag, src->comp_tag); buffer_copy_buffer(ds->comp_key, src->comp_key); array_free(ds->value); ds->value = array_init_array(src->value); @@ -22,6 +24,7 @@ static void data_config_free(data_unset *d) { buffer_free(ds->key); buffer_free(ds->op); + buffer_free(ds->comp_tag); buffer_free(ds->comp_key); array_free(ds->value); @@ -41,6 +44,7 @@ static void data_config_reset(data_unset *d) { /* reused array elements */ buffer_reset(ds->key); + buffer_reset(ds->comp_tag); buffer_reset(ds->comp_key); array_reset(ds->value); } @@ -130,6 +134,7 @@ data_config *data_config_init(void) { ds->key = buffer_init(); ds->op = buffer_init(); + ds->comp_tag = buffer_init(); ds->comp_key = buffer_init(); ds->value = array_init(); vector_config_weak_init(&ds->children); diff --git a/src/response.c b/src/response.c index bd0e7bbb..0a919a79 100644 --- a/src/response.c +++ b/src/response.c @@ -237,6 +237,7 @@ handler_t http_response_prepare(server *srv, connection *con) { con->conditional_is_valid[COMP_HTTP_REQUEST_METHOD] = 1; /* REQUEST_METHOD */ con->conditional_is_valid[COMP_HTTP_URL] = 1; /* HTTPurl */ con->conditional_is_valid[COMP_HTTP_QUERY_STRING] = 1; /* HTTPqs */ + con->conditional_is_valid[COMP_HTTP_REQUEST_HEADER] = 1; /* HTTP request header */ config_patch_connection(srv, con); /* do we have to downgrade to 1.0 ? */