nginx_process_request_and_response_body
Overview
nginx provides flexible way when processing header and body to meet different network env to achieve better performance, say nginx can send the request immediately after get the whole request headers, or send the request to upstream after get the entire body, when cache request body, we can cache it in memory if memory is large enough or cache it to a file.
Also we can cache the response body to a file or send it immediately to client, all are configurable!!!
Body processing
request
request header buffer
Before talking about request body, let’s say process header buffer first, here are directives related to request header
1 | Syntax: client_header_buffer_size size; |
Sets buffer size for reading client request header. For most requests, a buffer of 1K bytes is enough. However, if a request includes long cookies, or comes from a WAP client, it may not fit into 1K. If a request line or a request header field does not fit into this buffer then larger buffers, configured by the large_client_header_buffers directive, are allocated.
1 | Syntax: large_client_header_buffers number size; |
Sets the maximum number and size of buffers used for reading large client request header. A request line cannot exceed the size of one buffer
, or the 414 (Request-URI Too Large) error is returned to the client. A request header field(one header) cannot exceed the size of one buffer as well
, or the 400 (Bad Request) error is returned to the client. Buffers are allocated only on demand that means it's allocated only when 1K is not enough to hold request headers or request line
.
request body
1 | # It's clear to call client_request_buffering_on to align with others. |
When buffering is enabled, the entire request body is read from the client before sending the request to a proxied server
, send request(headers, then body) happens only when we receive the entire request body.
When buffering is disabled, the request body is sent to the proxied server immediately as it is received(request headers). In this case, the request cannot be passed to the next server if nginx already started sending the request body
.
As mentioned above when buffering is enabled, in some case request body is large, how can we cache it? nginx first uses memory, then disk for body caching, but if CPS is high and with large request body, it’s not a good way to buffer them all as it could use up disk or memory.
1 | Syntax: client_body_buffer_size size; |
Sets buffer size for reading client request body. In case the request body is larger than the buffer(part of unused header buffer + this buffer), the whole body or only its part is written to a temporary file(each request has only one temporary file)
, By default, buffer size is equal to two memory pages. This is 8K on x86, other 32-bit platforms, and x86-64. It is usually 16K on other 64-bit platforms.
Note: temporary file is unlink() after nginx open it, that means you CAN NOT see it even worker is writing data to it
, temporary file is deleted after get response header from upstream that means we send out entire request body
1 | # show fd of temporary file |
1 | Syntax: client_body_temp_path path [level1 [level2 [level3]]]; |
Defines a directory for storing temporary files holding client request bodies. Up to three-level subdirectory hierarchy can be used under the specified directory. For example, in the following configuration
1 | client_body_temp_path /spool/nginx/client_temp 1 2; |
a path to a temporary file might look like this:
1 | /spool/nginx/client_temp/7/45/00000123457 |
1 | Syntax: client_body_in_file_only on | clean | off; |
Determines whether nginx should save the entire client request body(no matter what size it is
) into a file, it's same file with proxy_request_buffering
directive. This directive can be used during debugging, or when using the $request_body_file variable.
When set to the value on, temporary files are not removed after request processing.
The value clean will cause the temporary files left after request processing to be removed.
no buffering request body conf
1 | proxy_request_buffering off; |
1 | Syntax: client_max_body_size size; |
Sets the maximum allowed size of the client request body, specified in the “Content-Length” request header field. If the size in a request exceeds the configured value, the 413 (Request Entity Too Large) error is returned to the client. Please be aware that browsers cannot correctly display this error. Setting size to 0 disables checking of client request body size
.
response
There are several directives used for control response, should we buffer it when necessary.
1 | # write to temporary file only when client is slow than upstream |
When buffering is enabled, nginx receives a response from the proxied server as soon as possible, saving it into the buffers set by the proxy_buffer_size and proxy_buffers directives
. If the whole response does not fit into memory, a part of it can be saved to a temporary file on the disk
. when buffering is enabled, nginx tries to receive enough body as much as possible, but if client is ready to write, we still send body to it during receiving, that means temporary file may be not used if client is faster than upstream
. buffering NOT mean sending to client only when receive entire response, it’s different with buffering for request.
When buffering is disabled, the response is passed to a client synchronously, immediately as it is received. nginx will not try to read the whole response from the proxied server.The maximum size of the data that nginx can receive from the server at a time
is set by the proxy_buffer_size
directive.
1 | Syntax: proxy_buffers number size; |
Sets the number and size of the buffers used for reading a response from the proxied server, for a single connection. By default, the buffer size is equal to one memory page. This is either 4K or 8K, depending on a platform.
1 | Syntax: proxy_max_temp_file_size size; |
When buffering of responses from the proxied server is enabled, and the whole response does not fit into the buffers set by the proxy_buffer_size and proxy_buffers directives, a part of the response can be saved to a temporary file. This directive sets the maximum size of the temporary file
. the temporary file is deleted automatically when request is finalize in ngx_http_upstream_finalize_request()
.
The zero value disables buffering of responses to temporary files.
1 | Syntax: proxy_temp_path path [level1 [level2 [level3]]]; |
Defines a directory for storing temporary files with data received from proxied servers. Up to three-level subdirectory hierarchy can be used underneath the specified directory. For example, in the following configuration
1 | proxy_temp_path /spool/nginx/proxy_temp 1 2; |
a temporary file might look like this:
1 | /spool/nginx/proxy_temp/7/45/00000123457 |
non buffering response
1 | proxy_buffering off |
buffering response
1 | proxy_buffering on; |
API related
Header
request header
1 | // build r->headers_in from request header |
response header
1 | // build header sent to client(set r->header_out) when parsed all response headers |
Body
request body
1 | // client is ready to read, read request and send it to upstream |
response Body
1 | // downstream is ready to write |