On Thu, Sep 29, 2011 at 3:25 PM, Evgeny Turnaev <[email protected]> wrote:
> 2011/9/29 Yaniv Aknin <[email protected]>:
>>
>> I'm happy you understand me now.
>> The problem is if I fix it the HTTP way, it means my WSGI app has to do
>> things that are the webserver's job (like gzip compression).
>> For example, I tried sending a 1,000 byte document with correct
>> Content-Length from my app, via nginx with gzip compression on. If I kill
>> the connection at the 500th byte, nginx happily ignores the fact it has a
>> 500 byte document with Content-Length of 1,000 bytes, removes the
>> Content-Length header, does gzip and adds chunked transfer encoding.
>
> This is indeed an nginx issue. Btw did you tried latest nginx?
> If it not works in latest nginx then possible workaround:
> * write a patch for nginx
> * disable gzip and pass content-length provided by wsgi app directly
> (maybe with uwsgi_pass_header) to browser the browser will show
> that a page don`t loaded.. dont know if it will cache. but still this
> is 200 ok. if you want 500 you have to teach
> nginx recognize that this is incomplete response.
> Also wsgi application may not provide already gzipped or transfer
> encoded content
> this is described in
> http://www.python.org/dev/peps/pep-0333/#other-http-features
> and 
> http://www.python.org/dev/peps/pep-0333/#handling-the-content-length-header
>
>> 2. Answering "fix your app so uwsgi will not die" is not a serious response
>> in my opinion. Maybe my app had a bug, maybe uWSGI had a bug, maybe any of
>> the libraries they use had a bug, maybe my kernel had a bug, maybe my system
>> administrator made a mistake. This is a possibility that I don't think you
>> can seriously ignore, and not necessarily something I can fix. I prefer a
>> 502 in production instead of an incorrect 200 OK anyday.
>> This is a serious and complicated issue, I'd be happy to meet in IRC and
>> further explain this to those interested.
>
> Sorry Yaniv, maybe i misunderstood you point a bit.
> But still: If you app have a bug: try/catch it. If a bug in kernel:
> nothing will help you really.
> The system administrators do really make errors :)
> Although i agree with you: sad that nginx doesn't support checking of
> body response against content-length header.
> Also i think this issue can be solved with a proper support of ETag by
> nginx - so that ETag of incomplete response and complete will differ,
> but this is more like workaround.

i don't think the problem *strictly* rests with nginx, but rather with
the well-known semantics of the HTTP/1.0 protocol:

http://www.w3.org/Protocols/HTTP/1.0/spec.html#BodyLength
"... If a Content-Length header field is present, its value in bytes
represents the length of the Entity-Body. Otherwise, the body length
is determined by the closing of the connection by the server. ...
Closing the connection cannot be used to indicate the end of a request
body, since it leaves no possibility for the server to send back a
response. Therefore, HTTP/1.0 requests containing an entity body must
include a valid Content-Length header field. If a request contains an
entity body and Content-Length is not specified, and the server does
not recognize or cannot calculate the length from other fields, then
the server should send a 400 (bad request) response."

... so in all correctness, nginx should fail with 400, but nobody
honors this because the front-end client-connection is really
HTTP/1.1, ie. keepalive/chunked (i don't think a missing
content-length is treated as 400 even if client is 1.0).

immediate issue is that nginx doesn't natively support HTTP/1.1 to
backends ... though i imagine this could technically be implemented by
uwsgi by special casing an nginx connection -- a workaround to relying
on a bottomless 1.0 connection.  uwsgi would need to [re]implement
chunked encoding between the nginx module and uwsgi, out-of-band, and
reassemble/remove the frames before actually handing each chunk to
nginx, yes?

... sounds annoying :-)  is there a way you (the app developer) could
append a finalizing "EOT" marker to your response?  perhaps you could
strip the marker on 200/OK, and have nginx redirect/kill if it never
shows before socket close.  i know nginx can do some interesting
matching via configuration file alone, but it might complicate/bloat
your setup, if it's possible at all.

--

C Anthony
_______________________________________________
uWSGI mailing list
[email protected]
http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi

Reply via email to