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