2011/9/30 C Anthony Risinger <[email protected]>: > 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).
This is not about 1.0 vs 1.1 Yaniv did send Content-length back to nginx and it didn't helped him because nginx does not checks length of body vs content-length header. And this wont change with http 1.1 support in nginx. > 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? Nginx already supports http1.1 in latest version (with keepalive support) to http fcgi and scgi backends. The bad thing about adding content-length header is buffering: nginx would have to buffer whole response body check the length and decide whatever it is 400 500 or 200 ok. You are suggesting that uwsgi should implement chunking and nginx should reassemble chunks: again if nginx will reassemble the chunks then it has to buffer response.(if nginx will not buffer response and stream chunks directly to client - and then in the middle of reseponse will find that length do not match - there is no way to tell cleint this is 500 or 400, 200 ok already sent). And response body can be really big or a workload can be big. Also there is no reason to chunking because nginx would still buffer whole response. So this is applicable only to small responses under low load and with accetable buffering (not a comet like and not willing to du chunked response in order to load client page faster because of early load of js/css by browser) > ... 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 > -- -------------------------------------------- Турнаев Евгений Викторович +7 906 875 09 43 -------------------------------------------- _______________________________________________ uWSGI mailing list [email protected] http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi
