bug of discarding request body

Maxim Dounin mdounin at mdounin.ru
Mon Nov 23 01:24:52 UTC 2015


Hello!

On Sun, Nov 22, 2015 at 04:21:36PM -0800, Shuxin Yang wrote:

>     I run into a bug which I believe it is about
> ngx_http_discard_request_body()
> (discard_body() for short). This bug is reproducible using the 1.9.7
> release.
> 
>   The discard_body() discards request body by reading it. However,
> the if the body is not ready yet (i.e.
> ngx_http_read_discarded_request_body()
> returns NGX_AGAIN), it still return NGX_OK.
> 
>   ngx_http_special_response_handler() (special_handler() for short) calls
> discard_body(). If the discard_body() returns NGX_OK, it does *NOT* disable
> keepalive connection, in the meantime, it sends out the special response
> before the request body is completely discarded. This cause the problem!

[...]

> Observeration/Analysis:
> ======================
>    If you strace the backend server, you will see it first send 403-response to
> the proxy, then call recvfrom() trying to get the body the R1.
> 
>    The recvfrom() does not get the body of the R1, instead it gets the leading
> part of the R2, and discard it.
> 
>    The subsequent call to recvfrom() get the trailing part of the R2. Nginx thought
> it is starting part of R2, and gives 400 response.

There is no problem in returning a response before reading the 
whole body.  

It looks like you've run into the old bug in the proxy module, 
which doesn't handle such responses in keepalive connections 
properly, see additional details here:

https://trac.nginx.org/nginx/ticket/669

Correct fix would be to stop nginx from re-using upstream 
connections where a request wasn't completely sent.

-- 
Maxim Dounin
http://nginx.org/



More information about the nginx mailing list