Skip to content

Commit 07b4ad0

Browse files
committed
pass_headers_out
1 parent 8975537 commit 07b4ad0

File tree

7 files changed

+122
-40
lines changed

7 files changed

+122
-40
lines changed

README.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,15 +361,15 @@ Example
361361

362362
tnt_pass_http_request
363363
------------------
364-
**syntax:** *tnt_pass_http_request [on|off|parse_args|unescape|pass_body]*
364+
**syntax:** *tnt_pass_http_request [on|off|parse_args|unescape|pass_body|pass_headers_out]*
365365

366366
**default:** *off*
367367

368368
**context:** *location, location if*
369369

370370
Allow to pass HTTP headers and queries to Tarantool stored procedures.
371371

372-
Examples
372+
Examples #1
373373
```nginx
374374
location tnt {
375375
# Also, tnt_pass_http_request can be used together with JSON communication
@@ -400,6 +400,30 @@ Examples
400400
req.body -- request body, type string
401401
end
402402
```
403+
Examples #2 (pass_headers_out)
404+
```nginx
405+
location @tnt {
406+
tnt_http_rest_methods get;
407+
tnt_pass_http_request on pass_headers_out;
408+
tnt_method tarantool_stored_procedure_name;
409+
tnt_pass 127.0.0.1:9999;
410+
}
411+
412+
location / {
413+
add_header "X-Req-time" "$request_time";
414+
proxy_pass http://backend;
415+
post_action @tnt;
416+
}
417+
```
418+
```lua
419+
function tarantool_stored_procedure_name(req, ...)
420+
req.headers -- lua table
421+
req.headers['X-Req-time'] -- set by add_header
422+
req.query -- string
423+
return true
424+
end
425+
```
426+
403427
```bash
404428
# Call tarantool_stored_procedure_name()
405429
$> wget NGINX_HOST/tarantool_stored_procedure_name/some/mega/path?q=1

src/ngx_http_tnt_handlers.c

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,49 @@
3737

3838
extern ngx_module_t ngx_http_tnt_module;
3939

40+
41+
static inline ngx_int_t
42+
ngx_http_tnt_copy_headers(struct tp *tp,
43+
ngx_list_t *headers,
44+
size_t *map_items)
45+
{
46+
size_t i = 0;
47+
ngx_table_elt_t *h;
48+
ngx_list_part_t *part;
49+
50+
if (headers->size > 0) {
51+
52+
part = &headers->part;
53+
h = part->elts;
54+
55+
for (;; i++) {
56+
57+
if (i >= part->nelts) {
58+
if (part->next == NULL) {
59+
break;
60+
}
61+
part = part->next;
62+
h = part->elts;
63+
i = 0;
64+
}
65+
66+
if (!tp_encode_str_map_item(tp,
67+
(const char *) h[i].key.data,
68+
h[i].key.len,
69+
(const char *) h[i].value.data,
70+
h[i].value.len) )
71+
{
72+
return NGX_ERROR;
73+
}
74+
75+
++(*map_items);
76+
}
77+
}
78+
79+
return NGX_OK;
80+
}
81+
82+
4083
static inline size_t
4184
ngx_http_tnt_get_output_size(
4285
ngx_http_request_t *r,
@@ -387,8 +430,6 @@ ngx_http_tnt_get_request_data(ngx_http_request_t *r,
387430
char *map_place;
388431
size_t root_items;
389432
size_t map_items;
390-
ngx_list_part_t *part;
391-
ngx_table_elt_t *h;
392433
ngx_buf_t *b;
393434
ngx_chain_t *body;
394435
char *p;
@@ -475,41 +516,24 @@ ngx_http_tnt_get_request_data(ngx_http_request_t *r,
475516
return NGX_ERROR;
476517
}
477518

478-
if (r->headers_in.headers.size) {
479-
480-
part = &r->headers_in.headers.part;
481-
h = part->elts;
482-
483-
size_t i = 0;
484-
for (;; i++) {
485-
486-
if (i >= part->nelts) {
487-
if (part->next == NULL) {
488-
break;
489-
}
490-
part = part->next;
491-
h = part->elts;
492-
i = 0;
493-
}
519+
if (ngx_http_tnt_copy_headers(tp, &r->headers_in.headers, &map_items) ==
520+
NGX_ERROR)
521+
{
522+
return NGX_ERROR;
523+
}
494524

495-
++map_items;
496-
if (!tp_encode_str_map_item(tp,
497-
(const char *)h[i].key.data,
498-
h[i].key.len,
499-
(const char *)h[i].value.data,
500-
h[i].value.len))
501-
{
502-
return NGX_ERROR;
503-
}
504-
}
525+
if ((tlcf->pass_http_request & NGX_TNT_CONF_PASS_HEADERS_OUT) &&
526+
(ngx_http_tnt_copy_headers(tp, &r->headers_out.headers, &map_items) ==
527+
NGX_ERROR) )
528+
{
529+
return NGX_ERROR;
505530
}
506531

507532
*(map_place++) = 0xdf;
508533
*(uint32_t *) map_place = mp_bswap_u32(map_items);
509534

510535
/* Encode body
511536
*/
512-
513537
if ((tlcf->pass_http_request & NGX_TNT_CONF_PASS_BODY) &&
514538
r->headers_in.content_length_n > 0 &&
515539
r->upstream->request_bufs )
@@ -521,8 +545,8 @@ ngx_http_tnt_get_request_data(ngx_http_request_t *r,
521545
}
522546

523547
int sz = mp_sizeof_str(r->headers_in.content_length_n);
524-
if (tp_ensure(tp, sz) == -1) {
525-
return NGX_ERROR;
548+
if (tp_ensure(tp, sz) == -1) {
549+
return NGX_ERROR;
526550
}
527551

528552
p = mp_encode_strl(tp->p, r->headers_in.content_length_n);

src/ngx_http_tnt_handlers.h

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

4040

4141
typedef enum ngx_tnt_conf_states {
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,
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,
47+
NGX_TNT_CONF_PASS_HEADERS_OUT = 32,
4748
} ngx_tnt_conf_states_e;
4849

4950
/** The structure hold the nginx location variables, e.g. loc_conf.

src/ngx_http_tnt_module.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ static ngx_conf_bitmask_t ngx_http_tnt_pass_http_request_masks[] = {
9494
{ ngx_string("parse_args"), NGX_TNT_CONF_PARSE_ARGS },
9595
{ ngx_string("unescape"), NGX_TNT_CONF_UNESCAPE },
9696
{ ngx_string("pass_body"), NGX_TNT_CONF_PASS_BODY },
97+
{ ngx_string("pass_headers_out"), NGX_TNT_CONF_PASS_HEADERS_OUT },
9798
{ ngx_null_string, 0 }
9899
};
99100

test/ngx_confs/tnt_server_test.conf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,5 +204,19 @@ http {
204204
tnt_method update;
205205
tnt_pass tnt;
206206
}
207+
208+
location @pass_headers_out {
209+
tnt_pass_http_request on pass_body pass_headers_out;
210+
tnt_http_rest_methods all;
211+
tnt_method test_headers_out;
212+
tnt_pass tnt;
213+
}
214+
215+
location /headers_out {
216+
add_header "x-added-header" $request_time;
217+
post_action @pass_headers_out;
218+
tnt_method update;
219+
tnt_pass tnt;
220+
}
207221
}
208222
}

test/test.lua

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
json=require('json')
2-
yaml=require('yaml')
1+
json = require('json')
2+
yaml = require('yaml')
3+
os = require('os')
34

45
function echo_1(a)
56
return {a}
@@ -128,3 +129,14 @@ function pass_body_handler(request, ...)
128129
end
129130
return { request, { ... } }
130131
end
132+
133+
function touch(req, ...)
134+
return {req, ... }
135+
end
136+
137+
function test_headers_out(req)
138+
if req.headers['x-added-header'] == nil then
139+
os.exit(1)
140+
end
141+
return true
142+
end

test/v24_features.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,9 @@
3131
preset_method_location = BASE_URL + '/dont_pass_body'
3232
result = post_success(preset_method_location, {"body": True}, {})
3333
assert (('body' in result[0]) == False), "body in result"
34+
35+
# =============
36+
#
37+
print('[+] Headers out')
38+
preset_method_location = BASE_URL + '/headers_out'
39+
post_success(preset_method_location, {"body": True}, {})

0 commit comments

Comments
 (0)