@@ -49,7 +49,6 @@ typedef struct {
4949typedef 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-
8271static ngx_int_t
8372ngx_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 );
10695static 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
109103static ngx_http_output_header_filter_pt ngx_http_next_header_filter ;
110104static 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+
527642static void *
528643ngx_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