@@ -26,11 +26,17 @@ typedef struct {
26
26
27
27
typedef struct {
28
28
ngx_flag_t enable ;
29
+ ngx_flag_t include_body ;
29
30
ngx_array_t * return_if_body_eq_rules ;
30
31
ngx_array_t * return_if_body_contains_rules ;
31
32
ngx_array_t * return_if_body_regex_rules ;
32
33
} ngx_http_if_request_body_conf_t ;
33
34
35
+ typedef struct {
36
+ ngx_int_t forward_status ;
37
+ ngx_flag_t include_body ;
38
+ } ngx_http_if_request_body_ctx_t ;
39
+
34
40
35
41
static void * ngx_http_if_request_body_create_conf (ngx_conf_t * cf );
36
42
static char * ngx_http_if_request_body_merge_conf (ngx_conf_t * cf , void * parent ,
@@ -48,6 +54,7 @@ static u_char *ngx_http_if_request_body_strncasestr(u_char *s1, size_t len1, u_c
48
54
49
55
static u_char * ngx_http_if_request_body_strnstr (u_char * s1 , size_t len1 , u_char * s2 , size_t len2 );
50
56
57
+ static ngx_int_t ngx_http_if_request_body_handler (ngx_http_request_t * r );
51
58
52
59
static ngx_command_t ngx_http_if_request_body_commands [] = {
53
60
@@ -58,6 +65,13 @@ static ngx_command_t ngx_http_if_request_body_commands[] = {
58
65
NGX_HTTP_LOC_CONF_OFFSET ,
59
66
offsetof(ngx_http_if_request_body_conf_t , enable ),
60
67
NULL },
68
+ { ngx_string ("return_with_body" ),
69
+ NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_FLAG ,
70
+ ngx_conf_set_flag_slot ,
71
+ // ngx_http_if_request_body_set_flag_slot
72
+ NGX_HTTP_LOC_CONF_OFFSET ,
73
+ offsetof(ngx_http_if_request_body_conf_t , include_body ),
74
+ NULL },
61
75
{ ngx_string ("return_status_if_body_eq" ),
62
76
NGX_HTTP_LOC_CONF |NGX_CONF_TAKE23 ,
63
77
ngx_http_if_request_body_set_if_eq ,
@@ -117,60 +131,72 @@ ngx_module_t ngx_http_if_request_body_module = {
117
131
};
118
132
119
133
120
- static ngx_http_request_body_filter_pt ngx_http_next_request_body_filter ;
121
-
134
+ // static ngx_http_request_body_filter_pt ngx_http_next_request_body_filter;
122
135
136
+ // Return the Final Status
123
137
static ngx_int_t
124
- ngx_http_if_request_body_filter (ngx_http_request_t * r , ngx_chain_t * in )
125
- {
138
+ ngx_http_if_request_body_filter (ngx_http_request_t * r ) {
126
139
u_char * p ;
127
140
ngx_str_t req_body ;
128
141
ngx_chain_t * cl ;
129
- ngx_http_if_request_body_conf_t * conf ;
142
+ ngx_http_if_request_body_conf_t * bcf ;
130
143
ngx_buf_t * b ;
131
144
size_t len ;
132
145
133
- conf = ngx_http_get_module_loc_conf (r , ngx_http_if_request_body_module );
134
-
135
- if (!conf -> enable ) {
136
- return ngx_http_next_request_body_filter (r , in );
137
- }
138
-
139
- len = 0 ;
140
-
141
146
ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
142
- "catch request body filter " );
147
+ "intercept request body and filtered " );
143
148
144
149
// TO GET THE LEN FIRST
145
- for (cl = in ; cl ; cl = cl -> next ) {
146
- b = cl -> buf ;
147
- if (b -> in_file ) {
148
- ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "insufficient client_body_buffer_size" );
150
+ if (r -> request_body == NULL || r -> request_body -> bufs == NULL ) {
151
+ goto SKIP_CHECKING ;
152
+ }
153
+
154
+ if (r -> request_body -> bufs -> next != NULL ) {
155
+ len = 0 ;
156
+ for (cl = r -> request_body -> bufs ; cl ; cl = cl -> next ) {
157
+ b = cl -> buf ;
158
+ if (b -> in_file ) {
159
+ ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "insufficient client_body_buffer_size, expand it before checking" );
160
+ goto SKIP_CHECKING ;
161
+ }
162
+ len += b -> last - b -> pos ;
163
+ }
164
+ if (len == 0 ) {
149
165
goto SKIP_CHECKING ;
150
166
}
151
- len += b -> last - b -> pos ;
152
- }
153
167
154
- p = req_body .data = ngx_palloc (r -> pool , len );
155
- req_body .len = len ;
156
168
157
- if (req_body .data == NULL ) {
158
- ngx_log_error (NGX_LOG_EMERG , r -> connection -> log , 0 , "insufficient memory." );
159
- return NGX_HTTP_INTERNAL_SERVER_ERROR ;
160
- }
169
+ p = req_body .data = ngx_palloc (r -> pool , len );
170
+ req_body .len = len ;
161
171
162
- for (cl = in ; cl ; cl = cl -> next ) {
163
- p = ngx_copy (p , cl -> buf -> pos , cl -> buf -> last - cl -> buf -> pos );
164
- }
172
+ if (p == NULL ) {
173
+ ngx_log_error (NGX_LOG_EMERG , r -> connection -> log , 0 , "insufficient memory." );
174
+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
175
+ }
165
176
166
-
177
+ for (cl = r -> request_body -> bufs ; cl ; cl = cl -> next ) {
178
+ p = ngx_copy (p , cl -> buf -> pos , cl -> buf -> last - cl -> buf -> pos );
179
+ }
180
+ } else {
181
+ b = r -> request_body -> bufs -> buf ;
182
+ if ( !b -> pos || (len = ngx_buf_size (b )) == 0 ) {
183
+ goto SKIP_CHECKING ;
184
+ }
185
+ req_body .data = b -> pos ;
186
+ req_body .len = len ;
187
+ }
188
+ // ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "request_line=%V \n \
189
+ // uri is %V\n \
190
+ // args is %V\n \
191
+ // extern is %V\n \
192
+ // unparsed_uri is %V\n \
193
+ // body size is %zu", &r->request_line, &r->uri, &r->args, &r->exten, &r->unparsed_uri, len);
167
194
ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
168
- "filtering body in: %V" , & req_body );
169
-
170
- // TODO CHECK THE RULE NOW
195
+ "checking body : | %V |" , & req_body );
171
196
172
- ngx_http_if_request_body_conf_t * bcf = ngx_http_get_module_loc_conf ( r , ngx_http_if_request_body_module );
197
+ // CHECK THE RULE NOW
173
198
199
+ bcf = ngx_http_get_module_loc_conf (r , ngx_http_if_request_body_module );
174
200
175
201
ngx_uint_t i , nelts ;
176
202
body_eq_rule * eq_rules ;
@@ -272,14 +298,10 @@ ngx_http_if_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
272
298
}
273
299
// REGEX RULE END
274
300
275
-
276
-
277
-
278
-
279
-
280
-
301
+ // Proceed to the next handler of the current phase.
302
+ // If the current handler is the last in the current phase, move to the next phase.
281
303
SKIP_CHECKING :
282
- return ngx_http_next_request_body_filter ( r , in ) ;
304
+ return NGX_DECLINED ;
283
305
}
284
306
285
307
@@ -294,6 +316,7 @@ ngx_http_if_request_body_create_conf(ngx_conf_t *cf)
294
316
}
295
317
296
318
conf -> enable = NGX_CONF_UNSET ;
319
+ conf -> include_body = NGX_CONF_UNSET ;
297
320
conf -> return_if_body_eq_rules = NGX_CONF_UNSET_PTR ;
298
321
conf -> return_if_body_contains_rules = NGX_CONF_UNSET_PTR ;
299
322
conf -> return_if_body_regex_rules = NGX_CONF_UNSET_PTR ;
@@ -309,6 +332,7 @@ ngx_http_if_request_body_merge_conf(ngx_conf_t *cf, void *parent, void *child)
309
332
ngx_http_if_request_body_conf_t * conf = child ;
310
333
311
334
ngx_conf_merge_value (conf -> enable , prev -> enable , 0 );
335
+ ngx_conf_merge_value (conf -> include_body , prev -> include_body , 1 );
312
336
313
337
ngx_conf_merge_ptr_value (conf -> return_if_body_eq_rules , prev -> return_if_body_eq_rules , NULL );
314
338
ngx_conf_merge_ptr_value (conf -> return_if_body_contains_rules , prev -> return_if_body_contains_rules , NULL );
@@ -321,15 +345,30 @@ ngx_http_if_request_body_merge_conf(ngx_conf_t *cf, void *parent, void *child)
321
345
static ngx_int_t
322
346
ngx_http_if_request_body_init (ngx_conf_t * cf )
323
347
{
324
- ngx_http_next_request_body_filter = ngx_http_top_request_body_filter ;
325
- ngx_http_top_request_body_filter = ngx_http_if_request_body_filter ;
348
+
349
+ ngx_http_handler_pt * h ;
350
+ ngx_http_core_main_conf_t * cmcf ;
351
+
352
+ // ngx_http_next_request_body_filter = ngx_http_top_request_body_filter;
353
+ // ngx_http_top_request_body_filter = ngx_http_if_request_body_filter;
354
+
355
+ cmcf = ngx_http_conf_get_module_main_conf (cf , ngx_http_core_module );
356
+
357
+ h = ngx_array_push (& cmcf -> phases [NGX_HTTP_PRECONTENT_PHASE ].handlers );
358
+ if (h == NULL ) {
359
+ return NGX_ERROR ;
360
+ }
361
+
362
+ * h = ngx_http_if_request_body_handler ;
363
+
364
+ return NGX_OK ;
326
365
327
366
return NGX_OK ;
328
367
}
329
368
330
369
static char *
331
370
ngx_http_if_request_body_set_if_eq_ (ngx_conf_t * cf , ngx_command_t * cmd , void * conf , ngx_flag_t is_starts_with ) {
332
- ngx_http_if_request_body_conf_t * bcf = conf ;
371
+ ngx_http_if_request_body_conf_t * bcf = conf ;
333
372
ngx_str_t * value ;
334
373
body_eq_rule * br ;
335
374
// The complex value is to resolve variable feature
@@ -531,6 +570,70 @@ ngx_http_if_request_body_set_if_regex(ngx_conf_t *cf, ngx_command_t *cmd, void *
531
570
}
532
571
533
572
573
+ static void
574
+ ngx_http_if_request_body_process (ngx_http_request_t * r ) {
575
+ ngx_http_if_request_body_ctx_t * ctx ;
576
+
577
+ ctx = ngx_http_get_module_ctx (r , ngx_http_if_request_body_module );
578
+
579
+ ctx -> forward_status = ngx_http_if_request_body_filter (r );
580
+
581
+ // In order to pass body as well when returning status
582
+ r -> preserve_body = ctx -> include_body ;
583
+
584
+ r -> write_event_handler = ngx_http_core_run_phases ;
585
+ ngx_http_core_run_phases (r );
586
+ }
587
+
588
+ /**
589
+ * This is Precontent Handler
590
+ */
591
+ static ngx_int_t
592
+ ngx_http_if_request_body_handler (ngx_http_request_t * r ){
593
+ ngx_int_t rc ;
594
+ ngx_http_if_request_body_ctx_t * ctx ;
595
+ ngx_http_if_request_body_conf_t * bcf ;
596
+
597
+ if (r != r -> main ) {
598
+ return NGX_DECLINED ;
599
+ }
600
+
601
+ bcf = ngx_http_get_module_loc_conf (r , ngx_http_if_request_body_module );
602
+
603
+ if (!bcf -> enable ) {
604
+ return NGX_DECLINED ;
605
+ }
606
+
607
+ ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "if request body handler" );
608
+
609
+ ctx = ngx_http_get_module_ctx (r , ngx_http_if_request_body_module );
610
+
611
+ if (ctx ) {
612
+ return ctx -> forward_status ;
613
+ }
614
+
615
+ ctx = ngx_pcalloc (r -> pool , sizeof (ngx_http_if_request_body_ctx_t ));
616
+ if (ctx == NULL ) {
617
+ return NGX_ERROR ;
618
+ }
619
+
620
+ ctx -> forward_status = NGX_DONE ;
621
+ ctx -> include_body = bcf -> include_body ;
622
+
623
+ ngx_http_set_ctx (r , ctx , ngx_http_if_request_body_module );
624
+
625
+ rc = ngx_http_read_client_request_body (r , ngx_http_if_request_body_process );
626
+ if (rc >= NGX_HTTP_SPECIAL_RESPONSE ) {
627
+ return rc ;
628
+ }
629
+
630
+ ngx_http_finalize_request (r , NGX_DONE );
631
+
632
+ return NGX_DONE ;
633
+ }
634
+
635
+
636
+
534
637
535
638
536
639
// char *
0 commit comments