Skip to content

Commit 1726636

Browse files
committed
tnt_eval did ignor some HTTP request (POST, PUT), it was fixed by adding a new version subrequest function, which works weel with content-based methods. Plus, update tests, bump version.
1 parent d3a43ba commit 1726636

File tree

9 files changed

+264
-150
lines changed

9 files changed

+264
-150
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ configure-debug:
6262
cd $(NGX_PATH) && \
6363
CFLAGS="$(DEV_CFLAGS)" $(NGX_CONFIGURE) \
6464
--prefix=$(PREFIX_PATH) \
65+
--with-http_addition_module \
6566
--add-module=$(MODULE_PATH) \
6667
--with-debug
6768

README.md

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ Tarantool - https://hub.docker.com/r/tarantool/tarantool
4444
* [tnt_pass](#tnt_pass)
4545
* [tnt_eval](#tnt_eval)
4646
* [tnt_eval_buffer_size](#tnt_eval_buffer_size)
47-
* [tnt_eval_subrequest_in_memory](#tnt_eval_subrequest_in_memory)
4847
* [tnt_http_methods](#tnt_http_methods)
4948
* [tnt_http_rest_methods](#tnt_http_rest_methods)
5049
* [tnt_pass_http_request](#tnt_pass_http_request)
@@ -331,7 +330,7 @@ Specify the Tarantool server backend.
331330
[Back to content](#content)
332331

333332
tnt_eval
334-
------------
333+
--------
335334
**syntax:** *tnt_eval $HTTP_STATUS_VAR_NAME $HTTP_BODY_VAR_NAME*
336335

337336
**default:** *no*
@@ -417,9 +416,6 @@ Example
417416
2) '$'-prefix is required as part of names, means tnt_eval http_code body { ... } is error,
418417
it should be tnt_eval $http_status $body { ... }.
419418

420-
3) Limitations. The contents of subrequests issued from within the tnt_eval block
421-
(like those fired by echo_subrequest) won't be captured properly.
422-
423419
[Back to content](#content)
424420

425421
tnt_eval_buffer_size
@@ -435,18 +431,6 @@ Specify the size of the buffer used for `tnt_eval`.
435431

436432
[Back to content](#content)
437433

438-
tnt_eval_subrequest_in_memory
439-
-----------------------------
440-
**syntax:** *tnt_eval_subrequest_in_memory flag*
441-
442-
**default:** *off*
443-
444-
**context:** *main, server, location*
445-
446-
Specify that subrequest (i.e. `tnt_eval`) will be executed in memory.
447-
448-
[Back to content](#content)
449-
450434
tnt_http_methods
451435
----------------
452436
**syntax:** *tnt_http_methods post, put, patch, delete, all*

src/ngx_http_tnt_eval_module.c

Lines changed: 157 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ typedef struct {
4949
typedef struct {
5050
ngx_array_t *variables;
5151
ngx_str_t eval_location;
52-
ngx_flag_t subrequest_in_memory;
5352
size_t buffer_size;
5453
} ngx_http_tnt_eval_loc_conf_t;
5554

@@ -69,16 +68,6 @@ typedef struct {
6968
} ngx_http_tnt_eval_ctx_t;
7069

7170

72-
typedef ngx_int_t (*ngx_http_tnt_eval_format_handler_pt)(ngx_http_request_t *r,
73-
ngx_http_tnt_eval_ctx_t *ctx);
74-
75-
76-
typedef struct {
77-
ngx_str_t content_type;
78-
ngx_http_tnt_eval_format_handler_pt handler;
79-
} ngx_http_tnt_eval_format_t;
80-
81-
8271
static ngx_int_t
8372
ngx_http_tnt_eval_init_variables(ngx_http_request_t *r,
8473
ngx_http_tnt_eval_ctx_t *ctx, ngx_http_tnt_eval_loc_conf_t *ecf);
@@ -105,6 +94,11 @@ static ngx_int_t ngx_http_tnt_eval_parse_meta(ngx_http_request_t *r,
10594
ngx_http_tnt_eval_ctx_t *ctx, ngx_http_variable_value_t *v);
10695
static ngx_int_t ngx_http_tnt_eval_output(ngx_http_request_t *r,
10796
ngx_http_tnt_eval_ctx_t *ctx);
97+
static ngx_int_t ngx_http_tnt_subrequest(ngx_http_request_t *r,
98+
ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
99+
ngx_http_post_subrequest_t *ps, ngx_uint_t flags);
100+
static void ngx_http_tnt_eval_finalize_request(ngx_http_request_t *r);
101+
108102

109103
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
110104
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
@@ -125,13 +119,6 @@ static ngx_command_t ngx_http_tnt_eval_commands[] = {
125119
0,
126120
NULL },
127121

128-
{ ngx_string("tnt_eval_subrequest_in_memory"),
129-
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
130-
ngx_conf_set_flag_slot,
131-
NGX_HTTP_LOC_CONF_OFFSET,
132-
offsetof(ngx_http_tnt_eval_loc_conf_t, subrequest_in_memory),
133-
NULL },
134-
135122
{ ngx_string("tnt_eval_buffer_size"),
136123
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
137124
ngx_conf_set_size_slot,
@@ -180,9 +167,9 @@ ngx_http_tnt_eval_handler(ngx_http_request_t *r)
180167
ngx_str_t args;
181168
ngx_str_t subrequest_uri;
182169
ngx_uint_t flags;
183-
ngx_http_tnt_eval_loc_conf_t *ecf;
184-
ngx_http_tnt_eval_ctx_t *ctx;
185-
ngx_http_tnt_eval_ctx_t *sr_ctx;
170+
ngx_http_tnt_eval_loc_conf_t *ecf;
171+
ngx_http_tnt_eval_ctx_t *ctx;
172+
ngx_http_tnt_eval_ctx_t *sr_ctx;
186173
ngx_http_request_t *sr;
187174
ngx_int_t rc;
188175
ngx_http_post_subrequest_t *psr;
@@ -195,6 +182,12 @@ ngx_http_tnt_eval_handler(ngx_http_request_t *r)
195182
return NGX_DECLINED;
196183
}
197184

185+
rc = ngx_http_read_client_request_body(r,
186+
ngx_http_tnt_eval_finalize_request);
187+
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
188+
return rc;
189+
}
190+
198191
ctx = ngx_http_get_module_ctx(r, ngx_http_tnt_eval_module);
199192
if (ctx == NULL) {
200193

@@ -254,36 +247,19 @@ ngx_http_tnt_eval_handler(ngx_http_request_t *r)
254247
psr->handler = ngx_http_tnt_eval_post_subrequest_handler;
255248
psr->data = ctx;
256249

257-
flags |= NGX_HTTP_SUBREQUEST_WAITED;
258-
259-
dd("subrequest in memory : %d", (int) ecf->subrequest_in_memory);
260-
261-
if (ecf->subrequest_in_memory) {
262-
flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY;
263-
} else {
264-
}
265-
266250
dd("issue subrequest");
267251

268-
rc = ngx_http_subrequest(r, &subrequest_uri, &args, &sr, psr, flags);
252+
flags |= NGX_HTTP_SUBREQUEST_WAITED;
269253

254+
rc = ngx_http_tnt_subrequest(r, &subrequest_uri, &args, &sr, psr, flags);
270255
if (rc == NGX_ERROR || rc == NGX_DONE) {
271256
return rc;
272257
}
273258

274-
sr->discard_body = 1;
275-
276-
/* we don't want to forward certain request headers to the subrequest */
277-
sr->headers_in.content_length_n = 0;
278-
sr->headers_in.content_length = NULL;
279-
sr->headers_in.content_type = NULL;
280-
#if (NGX_HTTP_GZIP)
281-
sr->headers_in.accept_encoding = NULL;
282-
#endif
283-
284259
ctx->in_progress = 1;
285260

286-
/* XXX we don't allow eval in subrequests, i think? */
261+
/** We don't allow eval in subrequests
262+
*/
287263
sr_ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_tnt_eval_ctx_t));
288264
if (sr_ctx == NULL) {
289265
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -524,6 +500,145 @@ ngx_http_tnt_eval_output(ngx_http_request_t *r,
524500
}
525501

526502

503+
static ngx_int_t
504+
ngx_http_tnt_subrequest(ngx_http_request_t *r,
505+
ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
506+
ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
507+
{
508+
ngx_time_t *tp;
509+
ngx_connection_t *c;
510+
ngx_http_request_t *sr;
511+
ngx_http_core_srv_conf_t *cscf;
512+
ngx_http_postponed_request_t *pr, *p;
513+
514+
if (r->subrequests == 0) {
515+
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
516+
"subrequests cycle while processing \"%V\"", uri);
517+
return NGX_ERROR;
518+
}
519+
520+
/*
521+
* 1000 is reserved for other purposes.
522+
*/
523+
if (r->main->count >= 65535 - 1000) {
524+
ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
525+
"request reference counter overflow "
526+
"while processing \"%V\"", uri);
527+
return NGX_ERROR;
528+
}
529+
530+
sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
531+
if (sr == NULL) {
532+
return NGX_ERROR;
533+
}
534+
535+
sr->signature = NGX_HTTP_MODULE;
536+
537+
c = r->connection;
538+
sr->connection = c;
539+
540+
sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
541+
if (sr->ctx == NULL) {
542+
return NGX_ERROR;
543+
}
544+
545+
if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
546+
sizeof(ngx_table_elt_t))
547+
!= NGX_OK)
548+
{
549+
return NGX_ERROR;
550+
}
551+
552+
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
553+
sr->main_conf = cscf->ctx->main_conf;
554+
sr->srv_conf = cscf->ctx->srv_conf;
555+
sr->loc_conf = cscf->ctx->loc_conf;
556+
557+
sr->pool = r->pool;
558+
559+
sr->method = r->method;
560+
sr->method_name = r->method_name;
561+
sr->http_version = r->http_version;
562+
563+
sr->request_line = r->request_line;
564+
sr->uri = *uri;
565+
566+
sr->headers_in = r->headers_in;
567+
sr->request_body = r->request_body;
568+
569+
if (args) {
570+
sr->args = *args;
571+
}
572+
573+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
574+
"http tnt subrequest \"%V?%V\"", uri, &sr->args);
575+
576+
sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
577+
sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
578+
579+
sr->unparsed_uri = r->unparsed_uri;
580+
sr->http_protocol = r->http_protocol;
581+
582+
ngx_http_set_exten(sr);
583+
584+
sr->main = r->main;
585+
sr->parent = r;
586+
sr->post_subrequest = ps;
587+
sr->read_event_handler = ngx_http_request_empty_handler;
588+
sr->write_event_handler = ngx_http_handler;
589+
590+
if (c->data == r && r->postponed == NULL) {
591+
c->data = sr;
592+
}
593+
594+
sr->variables = r->variables;
595+
596+
sr->log_handler = r->log_handler;
597+
598+
pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
599+
if (pr == NULL) {
600+
return NGX_ERROR;
601+
}
602+
603+
pr->request = sr;
604+
pr->out = NULL;
605+
pr->next = NULL;
606+
607+
if (r->postponed) {
608+
for (p = r->postponed; p->next; p = p->next) { /* void */ }
609+
p->next = pr;
610+
611+
} else {
612+
r->postponed = pr;
613+
}
614+
615+
sr->internal = 1;
616+
sr->discard_body = r->discard_body;
617+
sr->expect_tested = 1;
618+
sr->main_filter_need_in_memory = r->main_filter_need_in_memory;
619+
620+
sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
621+
sr->subrequests = r->subrequests - 1;
622+
623+
tp = ngx_timeofday();
624+
sr->start_sec = tp->sec;
625+
sr->start_msec = tp->msec;
626+
627+
r->main->count++;
628+
*psr = sr;
629+
630+
return ngx_http_post_request(sr, NULL);
631+
}
632+
633+
634+
static void
635+
ngx_http_tnt_eval_finalize_request(ngx_http_request_t *r)
636+
{
637+
dd("finalize request");
638+
ngx_http_finalize_request(r, NGX_DONE);
639+
}
640+
641+
527642
static void *
528643
ngx_http_tnt_eval_create_loc_conf(ngx_conf_t *cf)
529644
{
@@ -536,7 +651,6 @@ ngx_http_tnt_eval_create_loc_conf(ngx_conf_t *cf)
536651
}
537652

538653
conf->buffer_size = NGX_CONF_UNSET_SIZE;
539-
conf->subrequest_in_memory = NGX_CONF_UNSET;
540654

541655
return conf;
542656
}
@@ -551,8 +665,6 @@ ngx_http_tnt_eval_merge_loc_conf(ngx_conf_t *cf,
551665

552666
ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
553667
(size_t) ngx_pagesize * 16);
554-
ngx_conf_merge_value(conf->subrequest_in_memory,
555-
prev->subrequest_in_memory, 0);
556668

557669
return NGX_CONF_OK;
558670
}
@@ -836,10 +948,6 @@ ngx_http_tnt_eval_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
836948

837949
conf = ngx_http_get_module_loc_conf(r->parent, ngx_http_tnt_eval_module);
838950

839-
if (conf->subrequest_in_memory) {
840-
return ngx_http_next_body_filter(r, in);
841-
}
842-
843951
b = &ctx->buffer;
844952

845953
if (b->start == NULL) {

0 commit comments

Comments
 (0)