From 0d2d40e23192a281adaf88ce436723c8b7f5e9d3 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 2 Jun 2022 09:36:35 +0800 Subject: Summary: Var: removing all async stuff. No functional changes. --- src/nxt_http_variables.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'src/nxt_http_variables.c') diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index b765e177..c48f9ca3 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -7,14 +7,12 @@ #include -static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query, - nxt_str_t *str, void *ctx); -static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, - nxt_var_query_t *query, nxt_str_t *str, void *ctx); -static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query, - nxt_str_t *str, void *ctx); -static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_var_query_t *query, - nxt_str_t *str, void *ctx); +static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, + void *ctx); +static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, + void *ctx); +static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx); +static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx); static nxt_var_decl_t nxt_http_vars[] = { @@ -44,8 +42,7 @@ nxt_http_register_variables(void) static nxt_int_t -nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, - void *ctx) +nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx) { nxt_http_request_t *r; @@ -58,8 +55,7 @@ nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, static nxt_int_t -nxt_http_var_request_uri(nxt_task_t *task, nxt_var_query_t *query, - nxt_str_t *str, void *ctx) +nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx) { nxt_http_request_t *r; @@ -72,8 +68,7 @@ nxt_http_var_request_uri(nxt_task_t *task, nxt_var_query_t *query, static nxt_int_t -nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, - void *ctx) +nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx) { nxt_http_request_t *r; @@ -86,8 +81,7 @@ nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, static nxt_int_t -nxt_http_var_host(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, - void *ctx) +nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx) { nxt_http_request_t *r; -- cgit From 45b89e32577eef18e473d0c7ae24562e7efedcc0 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 14 Jul 2022 04:32:49 +0800 Subject: Var: dynamic variables support. This commit adds the variables $arg_NAME, $header_NAME, and $cookie_NAME. --- src/nxt_http_variables.c | 187 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 164 insertions(+), 23 deletions(-) (limited to 'src/nxt_http_variables.c') diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index c48f9ca3..79e66668 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -8,29 +8,47 @@ static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, - void *ctx); + void *ctx, uint16_t field); static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, - void *ctx); -static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx); -static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx); + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field); +static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field); +static nxt_int_t nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field); +static nxt_int_t nxt_http_var_header(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); static nxt_var_decl_t nxt_http_vars[] = { - { nxt_string("method"), - &nxt_http_var_method, - 0 }, - - { nxt_string("request_uri"), - &nxt_http_var_request_uri, - 0 }, - - { nxt_string("uri"), - &nxt_http_var_uri, - 0 }, - - { nxt_string("host"), - &nxt_http_var_host, - 0 }, + { + .name = nxt_string("method"), + .handler = nxt_http_var_method, + }, { + .name = nxt_string("request_uri"), + .handler = nxt_http_var_request_uri, + }, { + .name = nxt_string("uri"), + .handler = nxt_http_var_uri, + }, { + .name = nxt_string("host"), + .handler = nxt_http_var_host, + }, { + .name = nxt_string("arg"), + .handler = nxt_http_var_arg, + .field_hash = nxt_http_argument_hash, + }, { + .name = nxt_string("header"), + .handler = nxt_http_var_header, + .field_hash = nxt_http_header_hash, + }, { + .name = nxt_string("cookie"), + .handler = nxt_http_var_cookie, + .field_hash = nxt_http_cookie_hash, + }, }; @@ -42,7 +60,7 @@ nxt_http_register_variables(void) static nxt_int_t -nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx) +nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) { nxt_http_request_t *r; @@ -55,7 +73,8 @@ nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx) static nxt_int_t -nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx) +nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) { nxt_http_request_t *r; @@ -68,7 +87,7 @@ nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx) static nxt_int_t -nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx) +nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) { nxt_http_request_t *r; @@ -81,7 +100,7 @@ nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx) static nxt_int_t -nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx) +nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) { nxt_http_request_t *r; @@ -91,3 +110,125 @@ nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx) return NXT_OK; } + + +static nxt_int_t +nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +{ + nxt_array_t *args; + nxt_var_field_t *vf; + nxt_router_conf_t *rtcf; + nxt_http_request_t *r; + nxt_http_name_value_t *nv, *start; + + r = ctx; + + rtcf = r->conf->socket_conf->router_conf; + + vf = nxt_var_field_get(rtcf->var_fields, field); + + args = nxt_http_arguments_parse(r); + if (nxt_slow_path(args == NULL)) { + return NXT_ERROR; + } + + start = args->elts; + nv = start + args->nelts - 1; + + while (nv >= start) { + + if (vf->hash == nv->hash + && vf->name.length == nv->name_length + && nxt_memcmp(vf->name.start, nv->name, nv->name_length) == 0) + { + str->start = nv->value; + str->length = nv->value_length; + + return NXT_OK; + } + + nv--; + } + + nxt_str_null(str); + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_header(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +{ + nxt_var_field_t *vf; + nxt_http_field_t *f; + nxt_router_conf_t *rtcf; + nxt_http_request_t *r; + + r = ctx; + + rtcf = r->conf->socket_conf->router_conf; + + vf = nxt_var_field_get(rtcf->var_fields, field); + + nxt_list_each(f, r->fields) { + + if (vf->hash == f->hash + && vf->name.length == f->name_length + && nxt_strncasecmp(vf->name.start, f->name, f->name_length) == 0) + { + str->start = f->value; + str->length = f->value_length; + + return NXT_OK; + } + + } nxt_list_loop; + + nxt_str_null(str); + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +{ + nxt_array_t *cookies; + nxt_var_field_t *vf; + nxt_router_conf_t *rtcf; + nxt_http_request_t *r; + nxt_http_name_value_t *nv, *end; + + r = ctx; + + rtcf = r->conf->socket_conf->router_conf; + + vf = nxt_var_field_get(rtcf->var_fields, field); + + cookies = nxt_http_cookies_parse(r); + if (nxt_slow_path(cookies == NULL)) { + return NXT_ERROR; + } + + nv = cookies->elts; + end = nv + cookies->nelts; + + while (nv < end) { + + if (vf->hash == nv->hash + && vf->name.length == nv->name_length + && nxt_memcmp(vf->name.start, nv->name, nv->name_length) == 0) + { + str->start = nv->value; + str->length = nv->value_length; + + return NXT_OK; + } + + nv++; + } + + nxt_str_null(str); + + return NXT_OK; +} -- cgit From 8c5e2d5ce5cc31649f8900621d1b92d66100a687 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 14 Jul 2022 04:34:05 +0800 Subject: HTTP: added more variables. This commit adds the following variables: $remote_addr, $time_local, $request_line, $status, $body_bytes_sent, $header_referer, $header_user_agent. --- src/nxt_http_variables.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) (limited to 'src/nxt_http_variables.c') diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index 79e66668..837ef7b0 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -15,6 +15,22 @@ static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field); static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_remote_addr(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_time_local(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static u_char *nxt_http_log_date(u_char *buf, nxt_realtime_t *now, + struct tm *tm, size_t size, const char *format); +static nxt_int_t nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); static nxt_int_t nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field); static nxt_int_t nxt_http_var_header(nxt_task_t *task, nxt_str_t *str, @@ -36,6 +52,27 @@ static nxt_var_decl_t nxt_http_vars[] = { }, { .name = nxt_string("host"), .handler = nxt_http_var_host, + }, { + .name = nxt_string("remote_addr"), + .handler = nxt_http_var_remote_addr, + }, { + .name = nxt_string("time_local"), + .handler = nxt_http_var_time_local, + }, { + .name = nxt_string("request_line"), + .handler = nxt_http_var_request_line, + }, { + .name = nxt_string("status"), + .handler = nxt_http_var_status, + }, { + .name = nxt_string("body_bytes_sent"), + .handler = nxt_http_var_body_bytes_sent, + }, { + .name = nxt_string("header_referer"), + .handler = nxt_http_var_referer, + }, { + .name = nxt_string("header_user_agent"), + .handler = nxt_http_var_user_agent, }, { .name = nxt_string("arg"), .handler = nxt_http_var_arg, @@ -112,6 +149,204 @@ nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) } +static nxt_int_t +nxt_http_var_remote_addr(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + nxt_http_request_t *r; + + r = ctx; + + str->length = r->remote->address_length; + str->start = nxt_sockaddr_address(r->remote); + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_time_local(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + nxt_http_request_t *r; + + static nxt_time_string_t date_cache = { + (nxt_atomic_uint_t) -1, + nxt_http_log_date, + "%02d/%s/%4d:%02d:%02d:%02d %c%02d%02d", + nxt_length("31/Dec/1986:19:40:00 +0300"), + NXT_THREAD_TIME_LOCAL, + NXT_THREAD_TIME_SEC, + }; + + r = ctx; + + str->length = date_cache.size; + + str->start = nxt_mp_nget(r->mem_pool, str->length); + if (nxt_slow_path(str->start == NULL)) { + return NXT_ERROR; + } + + str->length = nxt_thread_time_string(task->thread, &date_cache, str->start) + - str->start; + + return NXT_OK; +} + + +static u_char * +nxt_http_log_date(u_char *buf, nxt_realtime_t *now, struct tm *tm, + size_t size, const char *format) +{ + u_char sign; + time_t gmtoff; + + static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + + gmtoff = nxt_timezone(tm) / 60; + + if (gmtoff < 0) { + gmtoff = -gmtoff; + sign = '-'; + + } else { + sign = '+'; + } + + return nxt_sprintf(buf, buf + size, format, + tm->tm_mday, month[tm->tm_mon], tm->tm_year + 1900, + tm->tm_hour, tm->tm_min, tm->tm_sec, + sign, gmtoff / 60, gmtoff % 60); +} + + +static nxt_int_t +nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + size_t length; + u_char *p, *start; + nxt_http_request_t *r; + + r = ctx; + + length = r->method->length + 1 + r->target.length + 1 + r->version.length; + + start = nxt_mp_nget(r->mem_pool, length); + if (nxt_slow_path(start == NULL)) { + return NXT_ERROR; + } + + p = start; + + if (r->method->length != 0) { + p = nxt_cpymem(p, r->method->start, r->method->length); + + if (r->target.length != 0) { + *p++ = ' '; + p = nxt_cpymem(p, r->target.start, r->target.length); + + if (r->version.length != 0) { + *p++ = ' '; + p = nxt_cpymem(p, r->version.start, r->version.length); + } + } + + } else { + *p++ = '-'; + } + + str->start = start; + str->length = p - start; + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + nxt_off_t bytes; + nxt_http_request_t *r; + + r = ctx; + + str->start = nxt_mp_nget(r->mem_pool, NXT_OFF_T_LEN); + if (nxt_slow_path(str->start == NULL)) { + return NXT_ERROR; + } + + bytes = nxt_http_proto[r->protocol].body_bytes_sent(task, r->proto); + + str->length = nxt_sprintf(str->start, str->start + NXT_OFF_T_LEN, "%O", + bytes) - str->start; + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +{ + nxt_http_request_t *r; + + r = ctx; + + str->start = nxt_mp_nget(r->mem_pool, 3); + if (nxt_slow_path(str->start == NULL)) { + return NXT_ERROR; + } + + str->length = nxt_sprintf(str->start, str->start + 3, "%03d", r->status) + - str->start; + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + nxt_http_request_t *r; + + r = ctx; + + if (r->referer != NULL) { + str->start = r->referer->value; + str->length = r->referer->value_length; + + } else { + nxt_str_null(str); + } + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + nxt_http_request_t *r; + + r = ctx; + + if (r->user_agent != NULL) { + str->start = r->user_agent->value; + str->length = r->user_agent->value_length; + + } else { + nxt_str_null(str); + } + + return NXT_OK; +} + + static nxt_int_t nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) { -- cgit From eebaff42eaef94f67f2232fc551f6d43c90c2e5c Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 6 May 2022 19:41:02 +0100 Subject: Var: added a $dollar variable that translates to a '$'. Allow $dollar (or ${dollar}) to translate to a literal $ to allow support for sub-delimiters in URIs. It is possible to have URLs like https://example.com/path/15$1588/9925$2976.html and thus it would be useful to be able to specify them in various bits of the unit config such as the location setting. However this hadn't been possible due to $ being used to denote variables for substitution. E.g $host. As was noted in the below GitHub issue it was suggested by @VBart to use $sign to represent a literal $, however I feel $dollar is more appropriate so we have a variable named after the thing it represents, also @tippexs found[0] that &dollar is used in HTML to represent a $, so there is some somewhat related precedent. (The other idea to use $$ was rejected in my original pull-request[1] for this issue.) This means the above URL could be specified as https://example.com/path/15${dollar}1588/9925${dollar}2976.html in the unit config. This is done by adding a variable called 'dollar' which is loaded into the variables hash table which translates into a literal $. This is then handled in nxt_var_next_part() where variables are parsed for lookup and $dollar is set for substitution by a literal '$'. Actual variable substitution happens in nxt_var_query_finish(). [0]: https://github.com/nginx/unit/pull/693#issuecomment-1130412323 [1]: https://github.com/nginx/unit/pull/693 Closes: https://github.com/nginx/unit/issues/675 --- src/nxt_http_variables.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/nxt_http_variables.c') diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index 837ef7b0..5a632b24 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -7,6 +7,8 @@ #include +static nxt_int_t nxt_http_var_dollar(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field); static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, @@ -41,6 +43,9 @@ static nxt_int_t nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str, static nxt_var_decl_t nxt_http_vars[] = { { + .name = nxt_string("dollar"), + .handler = nxt_http_var_dollar, + }, { .name = nxt_string("method"), .handler = nxt_http_var_method, }, { @@ -96,6 +101,15 @@ nxt_http_register_variables(void) } +static nxt_int_t +nxt_http_var_dollar(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +{ + nxt_str_set(str, "$"); + + return NXT_OK; +} + + static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) { -- cgit