comparison src/http/modules/ngx_http_log_module.c @ 6840:0cf4e82e7c48

Access log: support for json escaping.
author Valentin Bartenev <vbart@nginx.com>
date Thu, 15 Dec 2016 16:25:42 +0300
parents b3682580c1bd
children c36d160cd4e0
comparison
equal deleted inserted replaced
6839:32714e608629 6840:0cf4e82e7c48
124 u_char *buf, ngx_http_log_op_t *op); 124 u_char *buf, ngx_http_log_op_t *op);
125 static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf, 125 static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf,
126 ngx_http_log_op_t *op); 126 ngx_http_log_op_t *op);
127 127
128 static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf, 128 static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf,
129 ngx_http_log_op_t *op, ngx_str_t *value); 129 ngx_http_log_op_t *op, ngx_str_t *value, ngx_uint_t json);
130 static size_t ngx_http_log_variable_getlen(ngx_http_request_t *r, 130 static size_t ngx_http_log_variable_getlen(ngx_http_request_t *r,
131 uintptr_t data); 131 uintptr_t data);
132 static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, 132 static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
133 ngx_http_log_op_t *op); 133 ngx_http_log_op_t *op);
134 static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size); 134 static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size);
135 static size_t ngx_http_log_json_variable_getlen(ngx_http_request_t *r,
136 uintptr_t data);
137 static u_char *ngx_http_log_json_variable(ngx_http_request_t *r, u_char *buf,
138 ngx_http_log_op_t *op);
135 139
136 140
137 static void *ngx_http_log_create_main_conf(ngx_conf_t *cf); 141 static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
138 static void *ngx_http_log_create_loc_conf(ngx_conf_t *cf); 142 static void *ngx_http_log_create_loc_conf(ngx_conf_t *cf);
139 static char *ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, 143 static char *ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent,
907 } 911 }
908 912
909 913
910 static ngx_int_t 914 static ngx_int_t
911 ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op, 915 ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op,
912 ngx_str_t *value) 916 ngx_str_t *value, ngx_uint_t json)
913 { 917 {
914 ngx_int_t index; 918 ngx_int_t index;
915 919
916 index = ngx_http_get_variable_index(cf, value); 920 index = ngx_http_get_variable_index(cf, value);
917 if (index == NGX_ERROR) { 921 if (index == NGX_ERROR) {
918 return NGX_ERROR; 922 return NGX_ERROR;
919 } 923 }
920 924
921 op->len = 0; 925 op->len = 0;
922 op->getlen = ngx_http_log_variable_getlen; 926
923 op->run = ngx_http_log_variable; 927 if (json) {
928 op->getlen = ngx_http_log_json_variable_getlen;
929 op->run = ngx_http_log_json_variable;
930
931 } else {
932 op->getlen = ngx_http_log_variable_getlen;
933 op->run = ngx_http_log_variable;
934 }
935
924 op->data = index; 936 op->data = index;
925 937
926 return NGX_OK; 938 return NGX_OK;
927 } 939 }
928 940
1023 } 1035 }
1024 size--; 1036 size--;
1025 } 1037 }
1026 1038
1027 return (uintptr_t) dst; 1039 return (uintptr_t) dst;
1040 }
1041
1042
1043 static size_t
1044 ngx_http_log_json_variable_getlen(ngx_http_request_t *r, uintptr_t data)
1045 {
1046 uintptr_t len;
1047 ngx_http_variable_value_t *value;
1048
1049 value = ngx_http_get_indexed_variable(r, data);
1050
1051 if (value == NULL || value->not_found) {
1052 return 0;
1053 }
1054
1055 len = ngx_escape_json(NULL, value->data, value->len);
1056
1057 value->escape = len ? 1 : 0;
1058
1059 return value->len + len;
1060 }
1061
1062
1063 static u_char *
1064 ngx_http_log_json_variable(ngx_http_request_t *r, u_char *buf,
1065 ngx_http_log_op_t *op)
1066 {
1067 ngx_http_variable_value_t *value;
1068
1069 value = ngx_http_get_indexed_variable(r, op->data);
1070
1071 if (value == NULL || value->not_found) {
1072 return buf;
1073 }
1074
1075 if (value->escape == 0) {
1076 return ngx_cpymem(buf, value->data, value->len);
1077
1078 } else {
1079 return (u_char *) ngx_escape_json(buf, value->data, value->len);
1080 }
1028 } 1081 }
1029 1082
1030 1083
1031 static void * 1084 static void *
1032 ngx_http_log_create_main_conf(ngx_conf_t *cf) 1085 ngx_http_log_create_main_conf(ngx_conf_t *cf)
1489 { 1542 {
1490 u_char *data, *p, ch; 1543 u_char *data, *p, ch;
1491 size_t i, len; 1544 size_t i, len;
1492 ngx_str_t *value, var; 1545 ngx_str_t *value, var;
1493 ngx_int_t *flush; 1546 ngx_int_t *flush;
1494 ngx_uint_t bracket; 1547 ngx_uint_t bracket, json;
1495 ngx_http_log_op_t *op; 1548 ngx_http_log_op_t *op;
1496 ngx_http_log_var_t *v; 1549 ngx_http_log_var_t *v;
1497 1550
1551 json = 0;
1498 value = args->elts; 1552 value = args->elts;
1553
1554 if (s < args->nelts && ngx_strncmp(value[s].data, "escape=", 7) == 0) {
1555 data = value[s].data + 7;
1556
1557 if (ngx_strcmp(data, "json") == 0) {
1558 json = 1;
1559
1560 } else if (ngx_strcmp(data, "default") != 0) {
1561 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1562 "unknown log format escaping \"%s\"", data);
1563 return NGX_CONF_ERROR;
1564 }
1565
1566 s++;
1567 }
1499 1568
1500 for ( /* void */ ; s < args->nelts; s++) { 1569 for ( /* void */ ; s < args->nelts; s++) {
1501 1570
1502 i = 0; 1571 i = 0;
1503 1572
1573 1642
1574 goto found; 1643 goto found;
1575 } 1644 }
1576 } 1645 }
1577 1646
1578 if (ngx_http_log_variable_compile(cf, op, &var) != NGX_OK) { 1647 if (ngx_http_log_variable_compile(cf, op, &var, json)
1648 != NGX_OK)
1649 {
1579 return NGX_CONF_ERROR; 1650 return NGX_CONF_ERROR;
1580 } 1651 }
1581 1652
1582 if (flushes) { 1653 if (flushes) {
1583 1654