On Wed, Nov 25, 2009 at 2:03 PM, Tres Seaver <span dir="ltr"><<a href="mailto:tseaver@palladion.com">tseaver@palladion.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">Aaron Watters wrote:<br>
><br>
> --- On Wed, 11/25/09, Chris Dent <<a href="mailto:chris.dent@gmail.com">chris.dent@gmail.com</a>> wrote:<br>
><br>
>> From: Chris Dent <<a href="mailto:chris.dent@gmail.com">chris.dent@gmail.com</a>><br>
>> I can (barely) relate to some of the complaints that<br>
>> start_response is a pain in the ass, but environ, to me, is<br>
>> not broken.<br>
><br>
> I agree. It maps nicely onto the underlying protocol<br>
> and WSGI is supposed to be low level right?<br>
><br>
> The biggest problem with start_response is that after<br>
> you evaluate<br>
><br>
> iterable = application(env, start_response)<br>
><br>
> Sometimes the start_response has been called and sometimes<br>
> it hasn't, and this can break middlewares when they haven't<br>
> been tested both ways (repose.who for example seems to<br>
> assume it has been called).<br>
<br>
</div>Since version 1.0.13 (2009-04-24), repoze.who's middleware is very<br>
careful to dance around the fact that an application is not required to<br>
have called 'start_response' on return, but *must* call it before<br>
returning the first chunk from its iterator. That bit of flexibility in<br>
PEP 333 is likely there to support *some* use case, but it makes<br>
'start_response' a *big* pain to work with in middleware which needs to<br>
to "egress" processing of headers.<br></blockquote></div><div><br></div><div>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:</div>
<div><br></div><div>def file_app(req):</div><div> filename = ...</div><div> req.response.setHeader('Content-Type', mimetypes.guess_type(os.path.splitext(filename)[1])[0])</div><div> # I believe most did not stream by default...</div>
<div> req.response.stream()</div><div> fp = open(filename, 'rb')</div><div> while 1:</div><div> chunk = fp.read(4096)</div><div> if not chunk: break</div><div> req.response.write(chunk)</div>
<div><br></div><div>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.</div>
<br>-- <br>Ian Bicking | <a href="http://blog.ianbicking.org">http://blog.ianbicking.org</a> | <a href="http://topplabs.org/civichacker">http://topplabs.org/civichacker</a><br>