Skip to content

Commit 05c997c

Browse files
committed
tnt_pass_http_request - fixed a bug with merge bit mask; add a feature: pass_body
1 parent 8de67df commit 05c997c

File tree

8 files changed

+126
-25
lines changed

8 files changed

+126
-25
lines changed

src/ngx_http_tnt_handlers.c

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -379,17 +379,17 @@ ngx_http_tnt_encode_query_args(
379379

380380

381381
static inline ngx_int_t
382-
ngx_http_tnt_get_request_data(
383-
ngx_http_request_t *r,
384-
ngx_http_tnt_loc_conf_t *tlcf,
385-
struct tp *tp)
382+
ngx_http_tnt_get_request_data(ngx_http_request_t *r,
383+
ngx_http_tnt_loc_conf_t *tlcf,
384+
struct tp *tp)
386385
{
387386
char *root_map_place;
388387
char *map_place;
389388
size_t root_items;
390389
size_t map_items;
391390
ngx_list_part_t *part;
392391
ngx_table_elt_t *h;
392+
ngx_buf_t *b;
393393

394394
root_items = 0;
395395
root_map_place = tp->p;
@@ -438,12 +438,11 @@ ngx_http_tnt_get_request_data(
438438
++root_items;
439439

440440
if (!tp_encode_str(tp, "args", sizeof("args")-1)) {
441-
dd("parse args: tp_encode_str failed");
442441
return NGX_ERROR;
443442
}
443+
444444
map_place = tp->p;
445445
if (!tp_add(tp, 1 + sizeof(uint32_t))) {
446-
dd("parse args: tp_add failed");
447446
return NGX_ERROR;
448447
}
449448

@@ -452,7 +451,6 @@ ngx_http_tnt_get_request_data(
452451
if (ngx_http_tnt_encode_query_args(
453452
r, tlcf, tp, &map_items) == NGX_ERROR)
454453
{
455-
dd("parse args: ngx_http_tnt_encode_query_args failed");
456454
return NGX_ERROR;
457455
}
458456

@@ -465,15 +463,13 @@ ngx_http_tnt_get_request_data(
465463
++root_items;
466464

467465
if (!tp_encode_str(tp, "headers", sizeof("headers")-1)) {
468-
dd("parse headers: tp_encode_str failed");
469466
return NGX_ERROR;
470467
}
471468

472469
map_items = 0;
473470
map_place = tp->p;
474471

475472
if (!tp_add(tp, 1 + sizeof(uint32_t))) {
476-
dd("parse headers: tp_add failed");
477473
return NGX_ERROR;
478474
}
479475

@@ -501,7 +497,6 @@ ngx_http_tnt_get_request_data(
501497
(const char *)h[i].value.data,
502498
h[i].value.len))
503499
{
504-
dd("parse headers: tp_encode_str_map_item failed");
505500
return NGX_ERROR;
506501
}
507502
}
@@ -510,6 +505,45 @@ ngx_http_tnt_get_request_data(
510505
*(map_place++) = 0xdf;
511506
*(uint32_t *) map_place = mp_bswap_u32(map_items);
512507

508+
/* Encode body
509+
*/
510+
if ((tlcf->pass_http_request & NGX_TNT_CONF_PASS_BODY) &&
511+
r->headers_in.content_length_n > 0)
512+
{
513+
++root_items;
514+
515+
if (!tp_encode_str(tp, "body", sizeof("body") - 1)) {
516+
return NGX_ERROR;
517+
}
518+
519+
int sz = mp_sizeof_str(r->headers_in.content_length_n);
520+
if (tp_ensure(tp, sz) == -1) {
521+
return NGX_ERROR;
522+
}
523+
524+
525+
ngx_chain_t *body;
526+
char *p = mp_encode_strl(tp->p, r->headers_in.content_length_n);
527+
for (body = r->upstream->request_bufs; body; body = body->next) {
528+
529+
b = body->buf;
530+
531+
if (b->in_file) {
532+
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
533+
"tnt: in-file buffer found. aborted. "
534+
"consider increasing your 'client_body_buffer_size' "
535+
"setting");
536+
return NGX_ERROR;
537+
}
538+
539+
p = (char *) ngx_copy(p, b->pos, b->last - b->pos);
540+
}
541+
542+
if (!tp_add(tp, sz)) {
543+
return NGX_ERROR;
544+
}
545+
}
546+
513547
*(root_map_place++) = 0xdf;
514548
*(uint32_t *) root_map_place = mp_bswap_u32(root_items);
515549

@@ -595,10 +629,9 @@ ngx_http_tnt_reset_ctx(ngx_http_tnt_ctx_t *ctx)
595629
}
596630

597631

598-
ngx_int_t ngx_http_tnt_init_handlers(
599-
ngx_http_request_t *r,
600-
ngx_http_upstream_t *u,
601-
ngx_http_tnt_loc_conf_t *tlcf)
632+
ngx_int_t ngx_http_tnt_init_handlers(ngx_http_request_t *r,
633+
ngx_http_upstream_t *u,
634+
ngx_http_tnt_loc_conf_t *tlcf)
602635
{
603636
ngx_http_tnt_ctx_t *ctx;
604637

@@ -616,11 +649,17 @@ ngx_int_t ngx_http_tnt_init_handlers(
616649
u->abort_request = ngx_http_tnt_abort_request;
617650
u->finalize_request = ngx_http_tnt_finalize_request;
618651

619-
620-
if (r->headers_in.content_length_n > 0) {
621-
u->create_request = ngx_http_tnt_body_json_handler;
622-
} else {
652+
if (tlcf->pass_http_request & NGX_TNT_CONF_PASS_BODY) {
653+
dd("NGX_TNT_CONF_PASS_BODY");
623654
u->create_request = ngx_http_tnt_query_handler;
655+
} else {
656+
if (r->headers_in.content_length_n > 0) {
657+
dd("ngx_http_tnt_body_json_handler");
658+
u->create_request = ngx_http_tnt_body_json_handler;
659+
} else {
660+
dd("ngx_http_tnt_query_handler");
661+
u->create_request = ngx_http_tnt_query_handler;
662+
}
624663
}
625664

626665
return NGX_OK;

src/ngx_http_tnt_handlers.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@
3939

4040

4141
typedef enum ngx_tnt_conf_states {
42-
NGX_TNT_CONF_ON = 0x0001,
43-
NGX_TNT_CONF_OFF = 0x0002,
44-
NGX_TNT_CONF_PARSE_ARGS = 0x0004,
45-
NGX_TNT_CONF_UNESCAPE = 0x0008,
42+
NGX_TNT_CONF_ON = 1,
43+
NGX_TNT_CONF_OFF = 2,
44+
NGX_TNT_CONF_PARSE_ARGS = 4,
45+
NGX_TNT_CONF_UNESCAPE = 8,
46+
NGX_TNT_CONF_PASS_BODY = 16,
4647
} ngx_tnt_conf_states_e;
4748

4849
/** The structure hold the nginx location variables, e.g. loc_conf.
@@ -61,7 +62,7 @@ typedef struct {
6162
*/
6263
ngx_str_t method;
6364

64-
/** This is max allowed size of query + headers, the size in bytes
65+
/** This is max allowed size of query + headers + body, the size in bytes
6566
*/
6667
size_t pass_http_request_buffer_size;
6768

@@ -114,7 +115,7 @@ typedef struct {
114115
*/
115116
ngx_uint_t multireturn_skip_count;
116117

117-
ngx_array_t *headers_source;
118+
ngx_array_t *headers_source;
118119

119120
} ngx_http_tnt_loc_conf_t;
120121

src/ngx_http_tnt_module.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ static ngx_conf_bitmask_t ngx_http_tnt_pass_http_request_masks[] = {
9393
{ ngx_string("off"), NGX_TNT_CONF_OFF },
9494
{ ngx_string("parse_args"), NGX_TNT_CONF_PARSE_ARGS },
9595
{ ngx_string("unescape"), NGX_TNT_CONF_UNESCAPE },
96+
{ ngx_string("pass_body"), NGX_TNT_CONF_PASS_BODY },
9697
{ ngx_null_string, 0 }
9798
};
9899

src/ngx_http_tnt_version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@
3333
#ifndef NGX_HTTP_TNT_VERSION_H
3434
#define NGX_HTTP_TNT_VERSION_H 1
3535

36-
#define NGX_HTTP_TNT_MODULE_VERSION_STRING "v0.2.2-49-g1278ee5-dirty"
36+
#define NGX_HTTP_TNT_MODULE_VERSION_STRING "v2.3.2-dirty"
3737

3838
#endif

test/ngx_confs/tnt_server_test.conf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,5 +191,18 @@ http {
191191
tnt_pass tnt;
192192
}
193193

194+
location /pass_body {
195+
tnt_pass_http_request on pass_body;
196+
tnt_http_rest_methods all;
197+
tnt_method pass_body_handler;
198+
tnt_pass tnt;
199+
}
200+
201+
location /dont_pass_body {
202+
tnt_pass_http_request on;
203+
tnt_http_rest_methods all;
204+
tnt_method update;
205+
tnt_pass tnt;
206+
}
194207
}
195208
}

test/run_all.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ for i in {1..10}; do
1919
$WORK_DIR/v23_features.py 1> /dev/null || (
2020
echo "[-] $WORK_DIR/v23_features.py failed" && exit 1
2121
)
22+
$WORK_DIR/v24_features.py 1> /dev/null || (
23+
echo "[-] $WORK_DIR/v24_features.py failed" && exit 1
24+
)
2225
done
2326

2427
clients_pids=
@@ -35,6 +38,10 @@ for i in {1..3}; do
3538
echo "[-] $WORK_DIR/v23_features.py failed" && exit 1
3639
)` &
3740
clients_pids="$clients_pids $!"
41+
`$WORK_DIR/v24_features.py 1> /dev/null || (
42+
echo "[-] $WORK_DIR/v24_features.py failed" && exit 1
43+
)` &
44+
clients_pids="$clients_pids $!"
3845
done
3946
for job in $clients_pids; do
4047
wait $job

test/test.lua

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,10 @@ end
121121
function issue_71(request)
122122
return request
123123
end
124+
125+
function pass_body_handler(request, ...)
126+
if request.body == nil then
127+
error('request == NIL')
128+
end
129+
return { request, { ... } }
130+
end

test/v24_features.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/python
2+
# -_- encoding: utf8 -_-
3+
4+
import sys
5+
import time
6+
sys.path.append('./test')
7+
from http_utils import *
8+
9+
# =============
10+
#
11+
print('[+] Post/Put body')
12+
13+
preset_method_location = BASE_URL + '/pass_body'
14+
data = {"some":"custom", "json":[]}
15+
result = post_success(preset_method_location, data, {})
16+
assert (json.loads(result[0]['body']) == data), 'result != data'
17+
18+
# =============
19+
#
20+
print('[+] Post body - error')
21+
data = ""
22+
for i in range(1, 4096):
23+
data = data + str(time.time())
24+
preset_method_location = BASE_URL + '/pass_body'
25+
rc, result = post(preset_method_location, data, {})
26+
assert (rc == 500), "rc != 500"
27+
28+
# =============
29+
#
30+
print('[+] Body sould not pass')
31+
preset_method_location = BASE_URL + '/dont_pass_body'
32+
result = post_success(preset_method_location, {"body": True}, {})
33+
assert (('body' in result[0]) == False), "body in result"

0 commit comments

Comments
 (0)