How to avoid sending incomplete request data to backend if 499 error
Maxim Dounin
mdounin at mdounin.ru
Tue Nov 19 17:48:32 UTC 2019
Hello!
On Tue, Nov 19, 2019 at 10:29:37AM -0500, feanorknd wrote:
> Hello...
>
> Few days ago I have had this problem... let me explain with log lines:
>
> X.X.X.X - - [16/Nov/2019:04:36:17 +0100] "POST /api/budgets/new HTTP/2.0"
> 200 2239 "----" "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2 like Mac OS X)
> AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/86.0.276299193 Mobile/15E148
> Safari/605.1" Exec: "2.190" Conn: "10" Upstream Time: "2.185" Upstream
> Status: "200"
>
> X.X.X.X - - [16/Nov/2019:04:36:55 +0100] "POST /api/budgets/new HTTP/2.0"
> 499 0 ""----"" "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2 like Mac OS X)
> AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/86.0.276299193 Mobile/15E148
> Safari/605.1" Exec: "0.147" Conn: "1" Upstream Time: "0.142" Upstream
> Status: "-"
>
> In the first line, there is nothing of interest... just the POST request was
> completely fine.
>
> In the second request, there was a client disconnection and POST request was
> not complete, as given by the 499 logged error.
>
> The problem was:
> - the incomplete POST data was sent from nginx to the backend fastcgi server
> somehow.
> - that code did process the incomplete request data and generated a corrupt
> entry in certain database... another history.
In no particular order:
- By default, nginx will pass the request to the backend server
only when it's completely received from the client, including
the request body. You can change things by explicitly using
"fastcgi_request_buffering off;", but this shouldn't change things
much as long as your backend is properly written.
- Any backend server is expected to verify if it received complete
request, as the connection between nginx and backend can be
broken from unrelated reasons, such as network issues.
- An incomplete request will result in 400, not 499. The 499
error means that the request was complete, but the client closed
connection before the response was generated.
Given the above, most likely what you've seen was a connection
close by the client after sending a complete request. For
example, this might have happened when nginx was sending the
request body to the backend.
By default, if the client closes the connection - nginx closes the
connection with the backend to let the backend know that no
further request processing is needed. A properly written backend
is expected to handle this correctly, as it is anyway have to
check the request integrity.
If for some reason your backend cannot cope with this, there is
the fastcgi_ignore_client_abort directive to control this
behaviour (http://nginx.org/r/fastcgi_ignore_client_abort).
--
Maxim Dounin
http://mdounin.ru/
More information about the nginx
mailing list