Re: Antw: [PATCH 1 of 2] Access log: Support for disabling escaping

2018-02-28 Thread Vladimir Homutov
On Thu, Feb 22, 2018 at 06:12:52PM +0100, Johannes Baiter wrote:
> Sorry, I accidentally submitted an incomplete version of the patch.
> Here is the corrected version.
>

Hello,

I've slightly updated the patch (also note your mail client have broken
it - you may want to update settings to avoid this), please take a look.

See also ticket 1450: https://trac.nginx.org/nginx/ticket/1450

# HG changeset patch
# User Vladimir Homutov 
# Date 1519834295 -10800
#  Wed Feb 28 19:11:35 2018 +0300
# Node ID d420ce6b46768ea7eb23bdec84f992212293af19
# Parent  20f139e9ffa84f1a1db6039547cd35fc4534
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)
 

Antw: [PATCH 1 of 2] Access log: Support for disabling escaping

2018-02-22 Thread Johannes Baiter
Sorry, I accidentally submitted an incomplete version of the patch.
Here is the corrected version.

# HG changeset patch
# User Johannes Baiter 
# Date 1519312196 -3600
#  Thu Feb 22 16:09:56 2018 +0100
# Node ID 6c1e7ddade7dd75677cb2821f346e862866ba4e3
# Parent  aa60f5799a4cbfc6887ef099c588e84a75c69785
Access log: support for disabling escaping.

diff -r aa60f5799a4c -r 6c1e7ddade7d
src/http/modules/ngx_http_log_module.c
--- a/src/http/modules/ngx_http_log_module.cThu Feb 22 12:42:29 2018
+0300
+++ b/src/http/modules/ngx_http_log_module.cThu Feb 22 16:09:56 2018
+0100
@@ -90,6 +90,13 @@
 } ngx_http_log_var_t;
 
 
+typedef enum {
+ngx_http_log_escape_default = 0,
+ngx_http_log_escape_json,
+ngx_http_log_escape_none
+} ngx_http_log_escape_t;
+
+
 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,12 +133,16 @@
 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_http_log_escape_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,
 ngx_http_log_op_t *op);
 static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t
size);
+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 size_t ngx_http_log_json_variable_getlen(ngx_http_request_t
*r,
 uintptr_t data);
 static u_char *ngx_http_log_json_variable(ngx_http_request_t *r,
u_char *buf,
@@ -905,7 +916,7 @@
 
 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_http_log_escape_t escape)
 {
 ngx_int_t  index;
 
@@ -916,10 +927,14 @@
 
 op->len = 0;
 
-if (json) {
+if (escape == ngx_http_log_escape_json) {
 op->getlen = ngx_http_log_json_variable_getlen;
 op->run = ngx_http_log_json_variable;
 
+} else if (escape == ngx_http_log_escape_none) {
+op->getlen = ngx_http_log_unescaped_variable_getlen;
+op->run = ngx_http_log_unescaped_variable;
+
 } else {
 op->getlen = ngx_http_log_variable_getlen;
 op->run = ngx_http_log_variable;
@@ -1033,6 +1048,38 @@
 
 
 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 size_t
 ngx_http_log_json_variable_getlen(ngx_http_request_t *r, uintptr_t
data)
 {
 uintptr_t   len;
@@ -1536,19 +1583,21 @@
 size_t   i, len;
 ngx_str_t   *value, var;
 ngx_int_t   *flush;
-ngx_uint_t   bracket, json;
+ngx_uint_t   bracket;
 ngx_http_log_op_t   *op;
 ngx_http_log_var_t  *v;
+ngx_http_log_escape_t escape;
 
-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,
"unknown log format escaping \"%s\"",
data);
@@ -1636,7 +1685,7 @@
 }
 }
 
-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 -r aa60f5799a4c -r 6c1e7ddade7d
src/stream/ngx_stream_log_module.c
--- a/src/stream/ngx_stream_log_module.cThu Feb 22 12:42:29 2018
+0300
+++ b/src/stream/ngx_stream_log_module.cThu Feb 22 16:09:56 2018
+0100
@@ -89,6 +89,13 @@
 } ngx_stream_log_var_t;
 
 
+typedef enum {
+ngx_stream_log_escape_default = 0,
+