[Web-SIG] Collating follow-up on the future of WSGI

Graham Dumpleton graham.dumpleton at gmail.com
Wed Jan 20 07:03:19 EST 2016


> On 20 Jan 2016, at 10:25 PM, André Malo <nd at perlig.de> wrote:
> 
> * Cory Benfield wrote:
> 
>>> On 20 Jan 2016, at 06:04, Graham Dumpleton <graham.dumpleton at gmail.com>
>>> wrote:
>>> 
>>> For response content, if a WSGI application currently doesn’t set a
>>> Content-Length on response, A HTTP/1.1 web server is at liberty to chunk
>>> the response.
>>> 
>>> So I am not sure what is missing.
>> 
>> My specific concern is the distinction between “at liberty to” and
>> “required to”. Certain behaviours that make sense with chunked transfer
>> encoding do not make sense without it: for example, streaming API endpoints
>> that return events as they arrive.

Bidirectional HTTP is effectively a no go.

CGI, SCGI and FASTCGI implementations, mod_wsgi daemon mode and many HTTP proxies will often not actually start reading a response until they have managed to send the full content of the request. There are also various issues around buffering, especially with intermediaries.

So if your expectation is that that you can send a bit of a request, have client wait for a response for that bit, then send more request, wait for more response for that part of the request and so on, it isn’t going to work for most implementations.

This problem/issue and the lack of support for both way streaming has been the subjects of some RFCs. I can’t remember if this is the exact one I remember seeing before, but does appear relevant:

   https://www.ietf.org/rfc/rfc6202.txt <https://www.ietf.org/rfc/rfc6202.txt>

Anyway, the end result as I saw it was no one could be bothered supporting proper bidirectional HTTP as getting proxies/caches changed was going to be too hard.

The solution was to give up on it for HTTP/1.X and instead do it in HTTP/2 as upgrading a HTTP connection to something else generally had the effect of bypassing any intermediaries behaviour which would cause issues as then it would switch to streaming properly in both directions. So I think it is a lost cause to try and do it in HTTP/1.X and WSGI.

>> Sending this kind of response with a
>> HTTP/1.0-style content-length absent response (framed by connection
>> termination) is utterly confusing, especially as some APIs consider the
>> chunk framing to be semantic.
> 
> Those APIs are just broken then. The HTTP RFCs state very clearly [1], that 
> any hop may modify the transfer encoding. In other words: the transfer 
> encoding is transparent to the representation layer.

Yep. If framing was required you could never rely on the HTTP chunking. Framing had to be done in the actual data.

>> This can and does bite people, because while all major production WSGI
>> servers use chunked transfer encoding in this situation, not all WSGI
>> implementations do: in fact, wsgiref does not. This means that if an
>> application has a production design requirement to use chunked transfer
>> encoding in its responses it cannot rely on the server actually providing
>> it.
>> 
>> I see two solutions to this problem: we could mandate that HTTP/1.1
>> responses that have no content length must be chunked, rather than falling
>> back to HTTP/1.0 style connection-termination-framed responses, or we could
>> have servers stuff something in the environ dictionary that can be checked
>> by applications. Or, I suppose, we can conclude that this problem is not
>> large enough, and that it’s “caveat developer”.
> 
> WSGI is a gateway working with the representation layer. I think, it should 
> not concern itself with underlying transport issues that much.
> 
> Regarding chunked requests - in my own WSGI implementation I went the most 
> pragmatic way and simply provided a CONTENT_LENGTH of -1 for unknown request 
> sizes (it maps very well to file.read(size)). Something like this would be my 
> suggestion for a future WSGI spec.

I am assuming here you mean that -1 means return whatever you have available, or block until you have something.

Problem with that is that some implementations will use -1 as a default value to mean no argument supplied and so read all input.

So that could well conflict with some implementations.

Also, if it is going to block, how is it really different to reading with a block size. The whole think with chunking as noted above is that intermediates can change the chunking and so using framing of your own in the data where you know the size of each message at application layer is only way to reliability do it. So can’t see any benefit of -1 meaning give me whatever you have.

In general this is where you would be better to have a proper ASYNC API.

> Cheers,
> nd
> 
> [1] https://tools.ietf.org/html/rfc7230#section-3.3.1 <https://tools.ietf.org/html/rfc7230#section-3.3.1>
> -- 
> If God intended people to be naked, they would be born that way.
>  -- Oscar Wilde
> _______________________________________________
> Web-SIG mailing list
> Web-SIG at python.org <mailto:Web-SIG at python.org>
> Web SIG: http://www.python.org/sigs/web-sig <http://www.python.org/sigs/web-sig>
> Unsubscribe: https://mail.python.org/mailman/options/web-sig/graham.dumpleton%40gmail.com <https://mail.python.org/mailman/options/web-sig/graham.dumpleton%40gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/web-sig/attachments/20160120/d1d47593/attachment-0001.html>


More information about the Web-SIG mailing list