Skip to content

Commit 2d7d781

Browse files
committed
ngx-json-log: hexdump body variables (#25)
- $http_json_log_req_body_hexdump - $http_json_err_log_req_hexdump ``` [ "31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 31 |123456789ABCDEF1|", "32 33 34 35 36 .. .. .. .. .. .. .. .. .. .. .. |23456 |" ] ```
1 parent 91310bb commit 2d7d781

7 files changed

+305
-22
lines changed

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,21 @@ Example:
431431
"body": "Zm9v"
432432
}
433433
```
434+
435+
#### $http_json_log_req_body_hexdump;
436+
437+
Log request body encoded as hexdump array.
438+
It requires proxy_pass configuration at logging location.
439+
440+
Example:
441+
442+
```
443+
"hex": [
444+
"31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 30 |123456789ABCDEF0|",
445+
"31 32 33 34 35 36 .. .. .. .. .. .. .. .. .. .. |123456 |"
446+
]
447+
```
448+
434449
#### $http_json_log_resp_headers;
435450

436451
Creates a json object with available response headers.

src/ngx_http_json_log_filter_module.c

+32-6
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,12 @@ ngx_http_json_log_header_bad_request(ngx_http_request_t *r) {
314314
ngx_str_t lcname;
315315
ngx_http_variable_value_t *vv;
316316
ngx_uint_t varkey;
317+
318+
ngx_str_t name_hex = ngx_string("http_json_err_log_req_hexdump");
319+
ngx_str_t lcname_hex;
320+
ngx_http_variable_value_t *vv_hex;
321+
ngx_uint_t varkey_hex;
322+
317323
ngx_str_t payload;
318324

319325
#ifdef HTTP_JSON_LOG_KAFKA_ENABLED
@@ -351,12 +357,21 @@ ngx_http_json_log_header_bad_request(ngx_http_request_t *r) {
351357
lcname.len = name.len;
352358
lcname.data = ngx_pcalloc(r->pool, name.len);
353359
varkey = ngx_hash_strlow(lcname.data, name.data, name.len);
354-
355360
vv = ngx_http_get_variable(r, &lcname, varkey);
356361
if (vv) {
357362
ngx_http_json_log_set_variable_req_body(r,
358363
vv, (uintptr_t) &payload);
359364
}
365+
366+
lcname_hex.len = name_hex.len;
367+
lcname_hex.data = ngx_pcalloc(r->pool, name_hex.len);
368+
varkey_hex = ngx_hash_strlow(lcname_hex.data,
369+
name_hex.data, name_hex.len);
370+
vv_hex = ngx_http_get_variable(r, &lcname_hex, varkey_hex);
371+
if (vv_hex) {
372+
ngx_http_json_log_set_variable_req_body_hexdump(r,
373+
vv_hex, (uintptr_t) &payload);
374+
}
360375
}
361376
}
362377

@@ -570,11 +585,15 @@ static ngx_http_request_body_filter_pt ngx_http_next_request_body_filter;
570585
static ngx_int_t
571586
ngx_http_json_log_body_filter(ngx_http_request_t *r, ngx_chain_t *in) {
572587

573-
588+
ngx_str_t name = ngx_string("http_json_log_req_body");
574589
ngx_str_t lcname;
575590
ngx_http_variable_value_t *vv;
576591
ngx_uint_t varkey;
577-
ngx_str_t name = ngx_string("http_json_log_req_body");
592+
593+
ngx_str_t name_hex = ngx_string("http_json_log_req_body_hexdump");
594+
ngx_str_t lcname_hex;
595+
ngx_http_variable_value_t *vv_hex;
596+
ngx_uint_t varkey_hex;
578597

579598
ngx_chain_t *cl;
580599
size_t len = 0;
@@ -639,14 +658,21 @@ ngx_http_json_log_body_filter(ngx_http_request_t *r, ngx_chain_t *in) {
639658
lcname.len = name.len;
640659
lcname.data = ngx_pcalloc(r->pool, name.len);
641660
varkey = ngx_hash_strlow(lcname.data, name.data, name.len);
642-
643661
vv = ngx_http_get_variable(r, &lcname, varkey);
644-
645662
if (!vv) {
646663
return ngx_http_next_header_filter(r);
647664
}
648-
649665
ngx_http_json_log_set_variable_req_body(r, vv, (uintptr_t) &payload);
666+
667+
lcname_hex.len = name_hex.len;
668+
lcname_hex.data = ngx_pcalloc(r->pool, name_hex.len);
669+
varkey_hex = ngx_hash_strlow(lcname_hex.data, name_hex.data, name_hex.len);
670+
vv_hex = ngx_http_get_variable(r, &lcname_hex, varkey_hex);
671+
if (!vv_hex) {
672+
return ngx_http_next_header_filter(r);
673+
}
674+
ngx_http_json_log_set_variable_req_body_hexdump(r, vv_hex, (uintptr_t) &payload);
675+
650676
return ngx_http_next_request_body_filter(r, in);
651677
}
652678

src/ngx_http_json_log_variables.c

+92-16
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,22 @@
3333

3434
#include "ngx_http_json_log_variables.h"
3535
#include "ngx_json_log_text.h"
36+
#include "ngx_json_log_str.h"
3637

3738
#include <jansson.h>
3839

3940
#include <sys/types.h>
4041
#include <sys/stat.h>
4142
#include <unistd.h>
4243
#include <fcntl.h>
44+
#include <stdio.h>
4345

4446
typedef ngx_queue_t *(*get_body_queue_pt)(ngx_http_request_t *r);
4547

4648
static ngx_int_t
4749
ngx_http_json_log_get_variable_req_headers(ngx_http_request_t *r,
4850
ngx_http_variable_value_t *v, uintptr_t data);
4951

50-
51-
5252
/* variables list */
5353
static ngx_http_variable_t ngx_http_json_log_variables_list[] = {
5454
{ ngx_string("http_json_log_req_headers"),
@@ -70,11 +70,19 @@ static ngx_http_variable_t ngx_http_json_log_variables_list[] = {
7070
ngx_http_json_log_set_variable_req_body,
7171
NULL,
7272
0, 0, 0
73+
},
74+
{ ngx_string("http_json_log_req_body_hexdump"),
75+
ngx_http_json_log_set_variable_req_body_hexdump,
76+
NULL,
77+
0, 0, 0
78+
},
79+
{ ngx_string("http_json_err_log_req_hexdump"),
80+
ngx_http_json_log_set_variable_req_body_hexdump,
81+
NULL,
82+
0, 0, 0
7383
}
7484
};
7585

76-
77-
7886
ngx_http_variable_t *
7987
ngx_http_json_log_variables(size_t *len) {
8088

@@ -115,6 +123,10 @@ ngx_http_json_log_local_variable_needs_body_filter(ngx_str_t *name) {
115123
sizeof("http_json_log_req_body")) == 0) {
116124
return 1;
117125
}
126+
if (ngx_strncmp("http_json_log_req_body_hexdump", name->data,
127+
sizeof("http_json_log_req_body_hexdump")) == 0) {
128+
return 1;
129+
}
118130
return NGX_ERROR;
119131
}
120132

@@ -135,9 +147,10 @@ ngx_http_json_log_local_variable_needs_header_filter(ngx_str_t *name) {
135147
void
136148
ngx_http_json_log_register_variables(ngx_conf_t *cf) {
137149

138-
ngx_http_variable_t *v;
139-
size_t l = 0, local_vars_len;
140-
ngx_http_variable_t *local_vars = NULL;
150+
ngx_http_variable_t *v;
151+
ngx_http_variable_t *local_vars = NULL;
152+
size_t l = 0;
153+
size_t local_vars_len;
141154

142155
local_vars = ngx_http_json_log_variables(&local_vars_len);
143156
/* Register variables */
@@ -155,11 +168,11 @@ static ngx_int_t
155168
ngx_http_json_log_get_variable_req_headers(ngx_http_request_t *r,
156169
ngx_http_variable_value_t *v, uintptr_t data) {
157170

158-
ngx_uint_t i;
159-
ngx_list_part_t *part = &r->headers_in.headers.part;
160-
ngx_table_elt_t *header = part->elts;
161-
char *key = NULL;
162-
json_t *object = json_object();
171+
ngx_uint_t i;
172+
ngx_list_part_t *part = &r->headers_in.headers.part;
173+
ngx_table_elt_t *header = part->elts;
174+
char *key = NULL;
175+
json_t *object = json_object();
163176

164177
for (i = 0; i < part->nelts ; ++i) {
165178
if (!header[i].key.data || !header[i].key.len) {
@@ -183,7 +196,7 @@ void
183196
ngx_http_json_log_set_variable_resp_headers(ngx_http_request_t *r,
184197
ngx_http_variable_value_t *v, uintptr_t data) {
185198

186-
size_t i;
199+
size_t i;
187200
ngx_table_elt_t *header;
188201
ngx_array_t *headers = (ngx_array_t *) data;
189202
json_t *object;
@@ -227,20 +240,30 @@ ngx_http_json_log_set_variable_resp_headers(ngx_http_request_t *r,
227240
set_current_mem_pool(NULL);
228241
}
229242

230-
231243
void
232244
ngx_http_json_log_set_variable_req_body(ngx_http_request_t *r,
233245
ngx_http_variable_value_t *v, uintptr_t data) {
234246

235247
ngx_str_t base64;
236-
ngx_str_t *payload;
237248
json_t *object = NULL;
238-
payload = (ngx_str_t *) data;
249+
ngx_str_t *payload = (ngx_str_t *) data;
239250

240251
if (!payload || !payload->data) {
241252
return;
242253
}
243254

255+
/* Empty payload */
256+
if (!payload->len) {
257+
set_current_mem_pool(r->pool);
258+
object = json_stringn((const char *) "", 0);
259+
if (object) {
260+
v->valid = 1;
261+
v->data = (void *) object;
262+
}
263+
set_current_mem_pool(NULL);
264+
return;
265+
}
266+
244267
base64.len = ngx_base64_encoded_length(payload->len);
245268
base64.data = ngx_pcalloc(r->pool, base64.len);
246269
if (!base64.data) {
@@ -256,5 +279,58 @@ ngx_http_json_log_set_variable_req_body(ngx_http_request_t *r,
256279
v->data = (void *) object;
257280
}
258281
set_current_mem_pool(NULL);
282+
}
283+
284+
void
285+
ngx_http_json_log_set_variable_req_body_hexdump(ngx_http_request_t *r,
286+
ngx_http_variable_value_t *v, uintptr_t data) {
287+
288+
ngx_str_t hexdump;
289+
json_t *object = NULL;
290+
json_t *value = NULL;
291+
ngx_str_t *payload = (ngx_str_t *) data;
292+
size_t start, i;
259293

294+
if (!payload || !payload->data) {
295+
return;
296+
}
297+
298+
/* Empty payload */
299+
if (!payload->len) {
300+
set_current_mem_pool(r->pool);
301+
object = json_stringn((const char *) "", 0);
302+
if (object) {
303+
v->valid = 1;
304+
v->data = (void *) object;
305+
}
306+
set_current_mem_pool(NULL);
307+
return;
308+
}
309+
310+
hexdump.len = ngx_json_log_hexdump_length(payload->len, 16);
311+
hexdump.data = ngx_pcalloc(r->pool, hexdump.len);
312+
if (!hexdump.data) {
313+
return;
314+
}
315+
316+
ngx_json_log_hexdump(payload, &hexdump);
317+
318+
set_current_mem_pool(r->pool);
319+
320+
object = json_array();
321+
start = 0;
322+
for (i = 0; i < hexdump.len; ++i) {
323+
if (hexdump.data[i] == '\n') {
324+
value = json_stringn((const char *) hexdump.data+start, (i-start));
325+
json_array_append(object, value);
326+
++i;
327+
start = i;
328+
}
329+
}
330+
331+
if (object) {
332+
v->valid = 1;
333+
v->data = (void *) object;
334+
}
335+
set_current_mem_pool(NULL);
260336
}

src/ngx_http_json_log_variables.h

+5
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ void
4040
ngx_http_json_log_set_variable_req_body(ngx_http_request_t *r,
4141
ngx_http_variable_value_t *v, uintptr_t data);
4242

43+
void
44+
ngx_http_json_log_set_variable_req_body_hexdump(ngx_http_request_t *r,
45+
ngx_http_variable_value_t *v, uintptr_t data);
46+
4347
ngx_int_t
4448
ngx_http_json_log_is_local_variable(ngx_str_t *name);
4549

@@ -50,5 +54,6 @@ ngx_int_t
5054
ngx_http_json_log_local_variable_needs_header_filter(ngx_str_t *name);
5155

5256

57+
5358
#endif // __NGX_HTTP_JSON_LOG_VARIABLES_H__
5459

0 commit comments

Comments
 (0)