On Wed, Nov 25, 2009 at 2:03 PM, Tres Seaver <tsea...@palladion.com> wrote:
> Aaron Watters wrote: > > > > --- On Wed, 11/25/09, Chris Dent <chris.d...@gmail.com> wrote: > > > >> From: Chris Dent <chris.d...@gmail.com> > >> I can (barely) relate to some of the complaints that > >> start_response is a pain in the ass, but environ, to me, is > >> not broken. > > > > I agree. It maps nicely onto the underlying protocol > > and WSGI is supposed to be low level right? > > > > The biggest problem with start_response is that after > > you evaluate > > > > iterable = application(env, start_response) > > > > Sometimes the start_response has been called and sometimes > > it hasn't, and this can break middlewares when they haven't > > been tested both ways (repose.who for example seems to > > assume it has been called). > > Since version 1.0.13 (2009-04-24), repoze.who's middleware is very > careful to dance around the fact that an application is not required to > have called 'start_response' on return, but *must* call it before > returning the first chunk from its iterator. That bit of flexibility in > PEP 333 is likely there to support *some* use case, but it makes > 'start_response' a *big* pain to work with in middleware which needs to > to "egress" processing of headers. > Just in terms of history, I think I'm to blame on this one, as I argued quite vigorously for start_response. The reason being that at the time frameworks that had a concept of "streaming" usually did it by writing to the response. While the names were different depending on the framework, this was the common way to do streaming: def file_app(req): filename = ... req.response.setHeader('Content-Type', mimetypes.guess_type(os.path.splitext(filename)[1])[0]) # I believe most did not stream by default... req.response.stream() fp = open(filename, 'rb') while 1: chunk = fp.read(4096) if not chunk: break req.response.write(chunk) To support that style of streaming start_response was added. I think PJE also had some notion of Comet-style interactions, and maybe something related to async, leading to the specific restrictions on how written content should be handled. I still don't entirely understand the use case underlying that. But anyway, that's some of the motivation. start_response is still useful for retrofitting support for frameworks from time to time, but all the modern frameworks work differently these days making start_response seem less necessary. -- Ian Bicking | http://blog.ianbicking.org | http://topplabs.org/civichacker
_______________________________________________ Web-SIG mailing list Web-SIG@python.org Web SIG: http://www.python.org/sigs/web-sig Unsubscribe: http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com