# HG changeset patch # User Vladimir Homutov # Date 1519893775 -10800 # Node ID 265c29b0b8b8c54b1c623268481ed85324ce3c79 # Parent 81fae70d6cb81c67607931ec3ecc585a609c97e0 Access log: support for disabling escaping (ticket #1450). Based on patches by Johannes Baiter and Calin Don. diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c --- a/src/http/modules/ngx_http_log_module.c +++ b/src/http/modules/ngx_http_log_module.c @@ -90,6 +90,11 @@ typedef struct { } ngx_http_log_var_t; +#define NGX_HTTP_LOG_ESCAPE_DEFAULT 0 +#define NGX_HTTP_LOG_ESCAPE_JSON 1 +#define NGX_HTTP_LOG_ESCAPE_NONE 2 + + static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf, size_t len); static ssize_t ngx_http_log_script_write(ngx_http_request_t *r, @@ -126,7 +131,7 @@ static u_char *ngx_http_log_request_leng ngx_http_log_op_t *op); static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf, - ngx_http_log_op_t *op, ngx_str_t *value, ngx_uint_t json); + ngx_http_log_op_t *op, ngx_str_t *value, ngx_uint_t escape); static size_t ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data); static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, @@ -136,6 +141,10 @@ static size_t ngx_http_log_json_variable uintptr_t data); static u_char *ngx_http_log_json_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); +static size_t ngx_http_log_unescaped_variable_getlen(ngx_http_request_t *r, + uintptr_t data); +static u_char *ngx_http_log_unescaped_variable(ngx_http_request_t *r, + u_char *buf, ngx_http_log_op_t *op); static void *ngx_http_log_create_main_conf(ngx_conf_t *cf); @@ -905,7 +914,7 @@ ngx_http_log_request_length(ngx_http_req static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op, - ngx_str_t *value, ngx_uint_t json) + ngx_str_t *value, ngx_uint_t escape) { ngx_int_t index; @@ -916,11 +925,18 @@ ngx_http_log_variable_compile(ngx_conf_t op->len = 0; - if (json) { + switch (escape) { + case NGX_HTTP_LOG_ESCAPE_JSON: op->getlen = ngx_http_log_json_variable_getlen; op->run = ngx_http_log_json_variable; + break; - } else { + case NGX_HTTP_LOG_ESCAPE_NONE: + op->getlen = ngx_http_log_unescaped_variable_getlen; + op->run = ngx_http_log_unescaped_variable; + break; + + default: /* NGX_HTTP_LOG_ESCAPE_DEFAULT */ op->getlen = ngx_http_log_variable_getlen; op->run = ngx_http_log_variable; } @@ -1073,6 +1089,39 @@ ngx_http_log_json_variable(ngx_http_requ } +static size_t +ngx_http_log_unescaped_variable_getlen(ngx_http_request_t *r, uintptr_t data) +{ + ngx_http_variable_value_t *value; + + value = ngx_http_get_indexed_variable(r, data); + + if (value == NULL || value->not_found) { + return 0; + } + + value->escape = 0; + + return value->len; +} + + +static u_char * +ngx_http_log_unescaped_variable(ngx_http_request_t *r, u_char *buf, + ngx_http_log_op_t *op) +{ + ngx_http_variable_value_t *value; + + value = ngx_http_get_indexed_variable(r, op->data); + + if (value == NULL || value->not_found) { + return buf; + } + + return ngx_cpymem(buf, value->data, value->len); +} + + static void * ngx_http_log_create_main_conf(ngx_conf_t *cf) { @@ -1536,18 +1585,21 @@ ngx_http_log_compile_format(ngx_conf_t * size_t i, len; ngx_str_t *value, var; ngx_int_t *flush; - ngx_uint_t bracket, json; + ngx_uint_t bracket, escape; ngx_http_log_op_t *op; ngx_http_log_var_t *v; - json = 0; + escape = NGX_HTTP_LOG_ESCAPE_DEFAULT; value = args->elts; if (s < args->nelts && ngx_strncmp(value[s].data, "escape=", 7) == 0) { data = value[s].data + 7; if (ngx_strcmp(data, "json") == 0) { - json = 1; + escape = NGX_HTTP_LOG_ESCAPE_JSON; + + } else if (ngx_strcmp(data, "none") == 0) { + escape = NGX_HTTP_LOG_ESCAPE_NONE; } else if (ngx_strcmp(data, "default") != 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -1636,7 +1688,7 @@ ngx_http_log_compile_format(ngx_conf_t * } } - if (ngx_http_log_variable_compile(cf, op, &var, json) + if (ngx_http_log_variable_compile(cf, op, &var, escape) != NGX_OK) { return NGX_CONF_ERROR; diff --git a/src/stream/ngx_stream_log_module.c b/src/stream/ngx_stream_log_module.c --- a/src/stream/ngx_stream_log_module.c +++ b/src/stream/ngx_stream_log_module.c @@ -89,6 +89,11 @@ typedef struct { } ngx_stream_log_var_t; +#define NGX_STREAM_LOG_ESCAPE_DEFAULT 0 +#define NGX_STREAM_LOG_ESCAPE_JSON 1 +#define NGX_STREAM_LOG_ESCAPE_NONE 2 + + static void ngx_stream_log_write(ngx_stream_session_t *s, ngx_stream_log_t *log, u_char *buf, size_t len); static ssize_t ngx_stream_log_script_write(ngx_stream_session_t *s, @@ -106,7 +111,7 @@ static void ngx_stream_log_flush(ngx_ope static void ngx_stream_log_flush_handler(ngx_event_t *ev); static ngx_int_t ngx_stream_log_variable_compile(ngx_conf_t *cf, - ngx_stream_log_op_t *op, ngx_str_t *value, ngx_uint_t json); + ngx_stream_log_op_t *op, ngx_str_t *value, ngx_uint_t escape); static size_t ngx_stream_log_variable_getlen(ngx_stream_session_t *s, uintptr_t data); static u_char *ngx_stream_log_variable(ngx_stream_session_t *s, u_char *buf, @@ -116,6 +121,10 @@ static size_t ngx_stream_log_json_variab uintptr_t data); static u_char *ngx_stream_log_json_variable(ngx_stream_session_t *s, u_char *buf, ngx_stream_log_op_t *op); +static size_t ngx_stream_log_unescaped_variable_getlen(ngx_stream_session_t *s, + uintptr_t data); +static u_char *ngx_stream_log_unescaped_variable(ngx_stream_session_t *s, + u_char *buf, ngx_stream_log_op_t *op); static void *ngx_stream_log_create_main_conf(ngx_conf_t *cf); @@ -682,7 +691,7 @@ ngx_stream_log_copy_long(ngx_stream_sess static ngx_int_t ngx_stream_log_variable_compile(ngx_conf_t *cf, ngx_stream_log_op_t *op, - ngx_str_t *value, ngx_uint_t json) + ngx_str_t *value, ngx_uint_t escape) { ngx_int_t index; @@ -693,11 +702,18 @@ ngx_stream_log_variable_compile(ngx_conf op->len = 0; - if (json) { + switch (escape) { + case NGX_STREAM_LOG_ESCAPE_JSON: op->getlen = ngx_stream_log_json_variable_getlen; op->run = ngx_stream_log_json_variable; + break; - } else { + case NGX_STREAM_LOG_ESCAPE_NONE: + op->getlen = ngx_stream_log_unescaped_variable_getlen; + op->run = ngx_stream_log_unescaped_variable; + break; + + default: /* NGX_STREAM_LOG_ESCAPE_DEFAULT */ op->getlen = ngx_stream_log_variable_getlen; op->run = ngx_stream_log_variable; } @@ -851,6 +867,39 @@ ngx_stream_log_json_variable(ngx_stream_ } +static size_t +ngx_stream_log_unescaped_variable_getlen(ngx_stream_session_t *s, uintptr_t data) +{ + ngx_stream_variable_value_t *value; + + value = ngx_stream_get_indexed_variable(s, data); + + if (value == NULL || value->not_found) { + return 0; + } + + value->escape = 0; + + return value->len; +} + + +static u_char * +ngx_stream_log_unescaped_variable(ngx_stream_session_t *s, u_char *buf, + ngx_stream_log_op_t *op) +{ + ngx_stream_variable_value_t *value; + + value = ngx_stream_get_indexed_variable(s, op->data); + + if (value == NULL || value->not_found) { + return buf; + } + + return ngx_cpymem(buf, value->data, value->len); +} + + static void * ngx_stream_log_create_main_conf(ngx_conf_t *cf) { @@ -1265,17 +1314,20 @@ ngx_stream_log_compile_format(ngx_conf_t size_t i, len; ngx_str_t *value, var; ngx_int_t *flush; - ngx_uint_t bracket, json; + ngx_uint_t bracket, escape; ngx_stream_log_op_t *op; - json = 0; + escape = NGX_STREAM_LOG_ESCAPE_DEFAULT; value = args->elts; if (s < args->nelts && ngx_strncmp(value[s].data, "escape=", 7) == 0) { data = value[s].data + 7; if (ngx_strcmp(data, "json") == 0) { - json = 1; + escape = NGX_STREAM_LOG_ESCAPE_JSON; + + } else if (ngx_strcmp(data, "none") == 0) { + escape = NGX_STREAM_LOG_ESCAPE_NONE; } else if (ngx_strcmp(data, "default") != 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -1350,7 +1402,7 @@ ngx_stream_log_compile_format(ngx_conf_t goto invalid; } - if (ngx_stream_log_variable_compile(cf, op, &var, json) + if (ngx_stream_log_variable_compile(cf, op, &var, escape) != NGX_OK) { return NGX_CONF_ERROR;