# HG changeset patch # User Roman Arutyunyan # Date 1492616565 -10800 # Node ID a1d29eda04b606676407e1cf171c7b9283c21ffa # Parent 275c928ab386296ee72a0d45b7d7ec6d8ab637ef The HTTP request body section of the development guide. diff -r 275c928ab386 -r a1d29eda04b6 xml/en/docs/dev/development_guide.xml --- a/xml/en/docs/dev/development_guide.xml Wed Apr 19 18:36:37 2017 +0300 +++ b/xml/en/docs/dev/development_guide.xml Wed Apr 19 18:42:45 2017 +0300 @@ -5048,6 +5048,182 @@ +
+ + +For dealing with client request body, nginx provides the following functions: +ngx_http_read_client_request_body(r, post_handler) and +ngx_http_discard_request_body(r). +The first function reads the request body and makes it available via the +request_body request field. +The second function instructs nginx to discard (read and ignore) the request +body. +One of these functions must be called for every request. +Normally, it is done in the content handler. + + + +Reading or discarding client request body from a subrequest is not allowed. +It should always be done in the main request. +When a subrequest is created, it inherits the parent +request_body object which can be used by the subrequest if +the main request has previously read the request body. + + + +The function +ngx_http_read_client_request_body(r, post_handler) starts +the process of reading the request body. +When the body is completely read, the post_handler callback +is called to continue processing the request. +If request body is missing or already read, the callback is called immediately. +The function +ngx_http_read_client_request_body(r, post_handler) +allocates the request_body request field of type +ngx_http_request_body_t. +The field bufs of this object keeps the result as a buffer +chain. +The body can be saved in memory buffers or file buffers, if + +is not enough to fit the entire body in memory. + + + +The following example reads client request body and returns its size. + + + +ngx_int_t +ngx_http_foo_content_handler(ngx_http_request_t *r) +{ + ngx_int_t rc; + + rc = ngx_http_read_client_request_body(r, ngx_http_foo_init); + + if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { + /* error */ + return rc; + } + + return NGX_DONE; +} + + +void +ngx_http_foo_init(ngx_http_request_t *r) +{ + off_t len; + ngx_buf_t *b; + ngx_int_t rc; + ngx_chain_t *in, out; + + if (r->request_body == NULL) { + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + + len = 0; + + for (in = r->request_body->bufs; in; in = in->next) { + len += ngx_buf_size(in->buf); + } + + b = ngx_create_temp_buf(r->pool, NGX_OFF_T_LEN); + if (b == NULL) { + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + + b->last = ngx_sprintf(b->pos, "%O", len); + b->last_buf = (r == r->main) ? 1: 0; + b->last_in_chain = 1; + + r->headers_out.status = NGX_HTTP_OK; + r->headers_out.content_length_n = b->last - b->pos; + + rc = ngx_http_send_header(r); + + if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { + ngx_http_finalize_request(r, rc); + return; + } + + out.buf = b; + out.next = NULL; + + rc = ngx_http_output_filter(r, &out); + + ngx_http_finalize_request(r, rc); +} + + + +The following fields of the request affect the way request body is read: + + + + + +request_body_in_single_buf - read body to a single memory +buffer + + + +request_body_in_file_only - always read body to a file, +even if fits the memory buffer + + + +request_body_in_persistent_file - do not unlink the file +right after creation. +Such a file can be moved to another directory + + + +request_body_in_clean_file - unlink the file the when the +request is finalized. +This can be useful when a file was supposed to be moved to another directory +but eventually was not moved for some reason + + + +request_body_file_group_access - enable file group access. +By default a file is created with 0600 access mask. +When the flag is set, 0660 access mask is used + + + +request_body_file_log_level - log file errors with this +log level + + + +request_body_no_buffering - read request body without +buffering + + + + + +When the request_body_no_buffering flag is set, the +unbuffered mode of reading the request body is enabled. +In this mode, after calling +ngx_http_read_client_request_body(), the +bufs chain may keep only a part of the body. +To read the next part, the +ngx_http_read_unbuffered_request_body(r) function should be +called. +The return value of NGX_AGAIN and the request flag +reading_body indicate that more data is available. +If bufs is NULL after calling this function, there is +nothing to read at the moment. +The request callback read_event_handler will be called when +the next part of request body is available. + + +
+ +