post body

Dk Jack dnj0496 at gmail.com
Thu Aug 2 19:29:14 UTC 2018


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;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20180802/2c2e7020/attachment-0001.html>


More information about the nginx-devel mailing list