Skip to content

Commit 5f97bec

Browse files
committed
read client body in a better manner
1 parent 77ccd0b commit 5f97bec

File tree

1 file changed

+33
-32
lines changed

1 file changed

+33
-32
lines changed

nginx/modsecurity/ngx_http_modsecurity.c

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ typedef struct ngx_http_modsecurity_ctx_s {
4949
request_rec *req;
5050
ngx_chain_t *chain;
5151
ngx_buf_t buf;
52+
void **loc_conf;
5253
unsigned request_body_in_single_buf:1;
5354
unsigned request_body_in_file_only:1;
5455
} ngx_http_modsecurity_ctx_t;
@@ -393,7 +394,7 @@ modsecurity_read_body_cb(request_rec *r, char *outpos, unsigned int length,
393394
rest -= size;
394395
buf->file_pos += size;
395396
} else {
396-
return APR_ERROR;
397+
return -1;
397398
}
398399
}
399400

@@ -443,14 +444,13 @@ static ngx_int_t
443444
ngx_http_modsecurity_handler(ngx_http_request_t *r)
444445
{
445446
ngx_http_modsecurity_loc_conf_t *cf;
446-
ngx_http_core_loc_conf_t *clcf;
447+
ngx_http_core_loc_conf_t *clcf, *lcf;
447448
ngx_http_modsecurity_ctx_t *ctx;
448-
ngx_buf_t *buf;
449-
size_t preread;
450449
ngx_list_part_t *part;
451450
ngx_table_elt_t *h;
452451
ngx_uint_t i;
453452
ngx_int_t rc;
453+
void **loc_conf;
454454

455455
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: handler");
456456

@@ -544,36 +544,38 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r)
544544
if (r->method == NGX_HTTP_POST) {
545545
/* Processing POST request body, should we process PUT? */
546546
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: method POST");
547-
548-
/*
549-
* read client request body TODO: chunked request body
550-
*/
551547

552548
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
553549

554550
if (clcf == NULL) {
555551
return NGX_HTTP_INTERNAL_SERVER_ERROR;
556552
}
557-
558-
preread = r->header_in->last - r->header_in->pos;
559553

560-
/* force read_client_request_body to use r->header_in as body buffer */
561-
r->headers_in.content_length_n ++;
562-
563-
if ( (r->header_in->end - r->header_in->pos) < r->headers_in.content_length_n) {
564-
buf = ngx_create_temp_buf(r->pool, r->headers_in.content_length_n);
565-
if (buf == NULL) {
554+
ctx->loc_conf = r->loc_conf;
555+
/* hijack loc_conf so that we can receive any body length
556+
* TODO: nonblocking process & chuncked body
557+
*/
558+
if (clcf->client_body_buffer_size < r->headers_in.content_length_n) {
559+
560+
loc_conf = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
561+
if (loc_conf == NULL) {
562+
return NGX_HTTP_INTERNAL_SERVER_ERROR;
563+
}
564+
565+
lcf = ngx_pcalloc(r->pool, sizeof(ngx_http_core_loc_conf_t));
566+
if (lcf == NULL) {
566567
return NGX_HTTP_INTERNAL_SERVER_ERROR;
567568
}
569+
570+
ngx_memcpy(loc_conf, r->loc_conf, sizeof(void *) * ngx_http_max_module);
571+
ngx_memcpy(lcf, clcf, sizeof(ngx_http_core_loc_conf_t));
568572

569-
ngx_memcpy(buf->pos + 1, r->header_in->pos, preread);
570-
buf->last += preread + 1;
571-
r->header_in = buf;
572-
*r->header_in->pos = 0xff;
573-
} else {
574-
ngx_memmove(r->header_in->pos + 1, r->header_in->pos, preread);
575-
r->header_in->last ++;
576-
*r->header_in->pos = 0xff;
573+
ctx->loc_conf = r->loc_conf;
574+
r->loc_conf = loc_conf;
575+
576+
ngx_http_get_module_loc_conf(r, ngx_http_core_module) = lcf;
577+
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
578+
clcf->client_body_buffer_size = r->headers_in.content_length_n;
577579
}
578580

579581
ctx->request_body_in_single_buf = r->request_body_in_single_buf;
@@ -582,7 +584,7 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r)
582584
r->request_body_in_file_only = 0;
583585

584586
rc = ngx_http_read_client_request_body(r, ngx_http_modsecurity_request_body_handler);
585-
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
587+
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
586588
return rc;
587589
}
588590

@@ -608,19 +610,18 @@ ngx_http_modsecurity_request_body_handler(ngx_http_request_t *r)
608610

609611
if (ctx == NULL
610612
|| r->request_body->bufs == NULL
611-
|| *r->request_body->bufs->buf->pos != 0xff) {
613+
|| r->request_body->bufs->next != NULL) {
612614
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
613615
return;
614616
}
615-
617+
616618
r->request_body_in_single_buf = ctx->request_body_in_single_buf;
617619
r->request_body_in_file_only = ctx->request_body_in_file_only;
618-
619-
r->request_body->bufs->buf->pos ++;
620-
r->headers_in.content_length_n --;
621-
620+
r->header_in = r->request_body->bufs->buf;
622621
ctx->chain = r->request_body->bufs;
623-
622+
r->request_body = NULL;
623+
r->loc_conf = ctx->loc_conf;
624+
624625
ngx_http_finalize_request(r, ngx_http_modsecurity_pass_to_backend(r));
625626
return;
626627
}

0 commit comments

Comments
 (0)