Skip to content

Commit e4f2962

Browse files
committed
Update
1 parent 4678b2d commit e4f2962

File tree

1 file changed

+147
-44
lines changed

1 file changed

+147
-44
lines changed

ngx_http_if_request_body_module.c

Lines changed: 147 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,17 @@ typedef struct {
2626

2727
typedef struct {
2828
ngx_flag_t enable;
29+
ngx_flag_t include_body;
2930
ngx_array_t *return_if_body_eq_rules;
3031
ngx_array_t *return_if_body_contains_rules;
3132
ngx_array_t *return_if_body_regex_rules;
3233
} ngx_http_if_request_body_conf_t;
3334

35+
typedef struct {
36+
ngx_int_t forward_status;
37+
ngx_flag_t include_body;
38+
} ngx_http_if_request_body_ctx_t;
39+
3440

3541
static void *ngx_http_if_request_body_create_conf(ngx_conf_t *cf);
3642
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
4854

4955
static u_char *ngx_http_if_request_body_strnstr(u_char *s1, size_t len1, u_char *s2, size_t len2);
5056

57+
static ngx_int_t ngx_http_if_request_body_handler(ngx_http_request_t *r);
5158

5259
static ngx_command_t ngx_http_if_request_body_commands[] = {
5360

@@ -58,6 +65,13 @@ static ngx_command_t ngx_http_if_request_body_commands[] = {
5865
NGX_HTTP_LOC_CONF_OFFSET,
5966
offsetof(ngx_http_if_request_body_conf_t, enable),
6067
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 },
6175
{ ngx_string("return_status_if_body_eq"),
6276
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
6377
ngx_http_if_request_body_set_if_eq,
@@ -117,60 +131,72 @@ ngx_module_t ngx_http_if_request_body_module = {
117131
};
118132

119133

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;
122135

136+
// Return the Final Status
123137
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) {
126139
u_char *p;
127140
ngx_str_t req_body;
128141
ngx_chain_t *cl;
129-
ngx_http_if_request_body_conf_t *conf;
142+
ngx_http_if_request_body_conf_t *bcf;
130143
ngx_buf_t *b;
131144
size_t len;
132145

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-
141146
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
142-
"catch request body filter");
147+
"intercept request body and filtered");
143148

144149
// 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) {
149165
goto SKIP_CHECKING;
150166
}
151-
len += b->last - b->pos;
152-
}
153167

154-
p = req_body.data = ngx_palloc(r->pool, len);
155-
req_body.len = len;
156168

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;
161171

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+
}
165176

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);
167194
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);
171196

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
173198

199+
bcf = ngx_http_get_module_loc_conf(r, ngx_http_if_request_body_module);
174200

175201
ngx_uint_t i, nelts;
176202
body_eq_rule *eq_rules;
@@ -272,14 +298,10 @@ ngx_http_if_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
272298
}
273299
// REGEX RULE END
274300

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.
281303
SKIP_CHECKING:
282-
return ngx_http_next_request_body_filter(r, in);
304+
return NGX_DECLINED;
283305
}
284306

285307

@@ -294,6 +316,7 @@ ngx_http_if_request_body_create_conf(ngx_conf_t *cf)
294316
}
295317

296318
conf->enable = NGX_CONF_UNSET;
319+
conf->include_body = NGX_CONF_UNSET;
297320
conf->return_if_body_eq_rules = NGX_CONF_UNSET_PTR;
298321
conf->return_if_body_contains_rules = NGX_CONF_UNSET_PTR;
299322
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)
309332
ngx_http_if_request_body_conf_t *conf = child;
310333

311334
ngx_conf_merge_value(conf->enable, prev->enable, 0);
335+
ngx_conf_merge_value(conf->include_body, prev->include_body, 1);
312336

313337
ngx_conf_merge_ptr_value(conf->return_if_body_eq_rules, prev->return_if_body_eq_rules, NULL);
314338
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)
321345
static ngx_int_t
322346
ngx_http_if_request_body_init(ngx_conf_t *cf)
323347
{
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;
326365

327366
return NGX_OK;
328367
}
329368

330369
static char *
331370
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;
333372
ngx_str_t *value;
334373
body_eq_rule *br;
335374
// 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 *
531570
}
532571

533572

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+
534637

535638

536639
// char *

0 commit comments

Comments
 (0)