An HTTP POST payload is the data carried in the request body. An NGINX handler receives a request pointer, but that does not mean the body has already been loaded. It must ask NGINX to read the body before Rust can use its contents. section 4.4
To read a payload in a Rust NGINX handler:
- Call `ngx_http_read_client_request_body` with the request pointer and a callback. The callback runs when the body has been read. section 4.4
- In the callback, reject a null request pointer. Check that the request body, its buffer chain, and the buffer are initialized before dereferencing them. section 4.4 section 4.4.2
- Use the buffer’s start and end pointers to determine its length, then form a byte slice. If the payload is expected to be text, validate those bytes with `std::str::from_utf8` before returning a string slice tied to the request’s lifetime. section 4.4 section 4.4.2
A POST payload in practice
`curl -X POST -d '3 4 * 2 -' http://localhost:8080/calculate` sends `3 4 * 2 -` as the request body. The handler can log `Read request body: "3 4 * 2 -"`. At this stage, it does not write an HTTP response, so the curl command keeps waiting. section 4.4.2
unsafe fn request_body_as_str<'a>(
request: &'a ngx_http_request_t,
) -> Result<&'a str, &'static str> {
if request.request_body.is_null()
|| (*request.request_body).bufs.is_null()
|| (*(*request.request_body).bufs).buf.is_null()
{
return Err("Request body buffers
were not initialized as expected");
}
let buf = (*(*request.request_body).bufs).buf;
let start = (*buf).pos;
let len = (*buf).last.offset_from(start) as usize;
let body_bytes = std::slice::from_raw_parts(start, len);
let body_str = std::str::from_utf8(body_bytes)
.map_err(|_| "Body contains invalid UTF-8")?;
Ok(body_str)
}
The helper shows the boundary between NGINX-owned buffer pointers and a Rust string slice, including initialization checks and UTF-8 validation. section 4.4







