Hi,
In my module, I'd like to look into the post body to decide if the request
should be allowed to proceed to origin server or not. Based on the examples
I could find I've coded this in my module. After some trial and error it
seems to be working. I am not sure if my implementation is 100% correct. I
would appreciate it if someone can go over my code below and let me know if
my implementation is correct. Especially, the body_complete_handler. Thanks.
Regards,
Dk.
static ngx_int_t mod_setup_body_handler(ngx_http_request_t* r);
static void mod_body_complete_handler(ngx_http_request_t* r);
static ngx_int_t mod_extract_post_body(ngx_http_request_t *r, char *data,
size_t *dsize);
static ngx_int_t
ngx_http_request_handler(ngx_http_request_t *r)
{
....
if ((NGX_HTTP_POST == r->method) || (NGX_HTTP_PUT == r->method)) {
return mod_setup_body_handler(r);
}
...
}
ngx_int_t
mod_setup_body_handler(ngx_http_request_t* r)
{
ngx_int_t rc;
r->request_body_in_single_buf = 1;
r->request_body_in_persistent_file = 1;
r->request_body_in_clean_file = 1;
rc = ngx_http_read_client_request_body(r, mod_body_complete_handler);
if (rc == NGX_ERROR) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "read req. body
error");
return rc;
}
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "read req. body
error. special response");
return rc;
}
if (rc == NGX_AGAIN) {
/*
* nginx will call the body_received when needed. Returning
* NGX_DONE will prevent nginx from calling ngx_http_finalize_request
* (which we will call in body_received)
*/
return NGX_DONE;
}
return NGX_DECLINED;
}
void
mod_body_complete_handler(ngx_http_request_t* r)
{
ngx_http_request_t* r = mNginxRequest;
if(r->request_body == NULL) {
// callback was called but body is empty. Setup handler again.
mod_setup_body_handler(bh_ptr);
return;
} else if (r->request_body->rest) {
// we don't have the complete body. Complete callback will be called
again.
return;
}
if (NULL == mNginxRequest->request_body->temp_file) {
size_t dsize = 64*1024;
char data[dsize]
if (mod_extract_post_body(r, data, dsize) == NGX_OK) {
// we have the complete body.
int rc = mod_allow_request(body, dsize); // returns NGX_OK or 4XX.
if (rc != NGX_OK) {
// allow req. has already sent a custom response if rc != NGX_OK.
ngx_http_finalize_request(r, NGX_OK);
return;
}
}
}
// ???? not having this cause request to hang.
ngx_http_core_run_phases(r);
}
ngx_int_t
mod_extract_post_body(ngx_http_request_t *r, char *data, size_t *dsize)
{
size_t buf_size = *dsize;
if (NULL == r->request_body->temp_file) {
// we have body in buffer chain.
ngx_buf_t *buf;
ngx_chain_t *cl;
size_t data_start_pos = 0;
cl = r->request_body->bufs;
// copy the body into our temporary buffer.
for (;NULL != cl; cl = cl->next) {
buf = cl->buf;
size_t bsize = buf->last - buf->pos;
if ((data_start_pos+bsize) > buf_size) {
// data is bigger than the input buffer size, abort
*dsize = data_start_pos;
*(data+*dsize) = '\0';
return NGX_ERROR;
}
ngx_memcpy((data+data_start_pos), buf->pos, bsize);
data_start_pos += bsize;
}
*dsize = data_start_pos;
*(data+*dsize) = '\0';
return NGX_OK;
} else {
// body in file not implemented yet.
}
return NGX_ERROR;
}
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel