[Web-SIG] Re: Bill's comments on WSGI draft 1.4

Ian Bicking ianb at colorstudy.com
Thu Sep 2 22:38:31 CEST 2004


Bill Janssen wrote:
> I think we need some terminology that I don't remember seeing.  There
> are two sides to WSGI, the server side, which I'll call the "socket",
> and the framework side, which I'll call the "plug".  If there are
> other terms already in use, please let me know.

Generally we're using the terms "server" and "application".  And 
"middleware" is both a server and application.

> Let me ask first, has anyone written a "socket" layer for Medusa?
> 
> 
>>>1.  The "environ" parameter must be a Python dict: I think subclasses
>>>should be allowed.
>>
>>[...various reasons why this might be a bad idea are introducted...]
>>These are "practicality beats purity" argument, so I need to see some 
>>*practical* applications of dictionary subclasses that would be useful 
>>enough to outweigh both of the above issues.
> 
> 
> Phillip, these are good engineering reasons for socket developers not
> to use subclasses, but that restriction doesn't belong in WSGI.  They
> may have other reasons for using subclasses that we haven't thought of
> (perhaps because they're using these dicts for additional purposes
> besides WSGI), and they should be allowed to use them.  You don't want
> to try to fix things out of scope of this work.

The restriction is kind of there for the benefit of middleware, so that 
middleware can rewrite the environment without having to worry about 
losing anything (except parts it explicitly leaves out).  By requiring 
it to be a dictionary, you can be sure that there are no side effects, 
no unusual requirements, it's consistent, and you can recreate a 
completely equivalent object.  It means the environment is required to 
be a dumb container.

The restriction that isinstance(environ, dict) be true isn't much of a 
requirement at all, because subclasses of dictionaries can override 
pretty much everything they care to.  If isinstance was the only 
requirement, it might as well be required that the environment has a 
dictionary interface.

>>These restrictions are intended to simplify servers and middleware; nobody 
>>has yet presented an example of a scenario where this imposed any practical 
>>limitation.
> 
> 
> Here's a scenario for you: I want to return a valid HTTP header that
> your WSGI layer doesn't allow!  For example, accented Latin-1
> characters, which are valid in the Reason-Phrase.  Or for another
> example, a multi-line header value, which I actually use quite a bit,
> and which is perfectly valid in HTTP, and which your prohibition on
> control characters in header values breaks.

Is an accented Latin-1 character a control character?  I would have 
though a control character meant a character with a code less than 32.

>>Are you aware of any 
>>applications that currently fold their headers, or transmit ISO-8859-1 
>>characters without using the encoding prescribed by RFC 2047?  Is there a 
>>practical use case for either one?
> 
> 
> Whether or not our limited group currently knows of such a case is
> immaterial.  This is an overly restrictive limitation with nothing,
> I'm afraid, but religion for its justification.  Aside from clueless
> implementors (against which the gods themselves strive in vain), why
> would allowing any valid header value be a problem?

Because it requires more work to parse and manipulate a more permissive 
standard.  You have to worry about corner cases.

>>* In order to ensure safe interpretation, smart middleware and server 
>>developers will have to write routines to *unfold* potentially-folded 
>>headers; why not just disallow folding to begin with?
> 
> 
> Because it's allowed in the HTTP spec, and this is a general-purpose
> HTTP framework layer.

But it doesn't *matter*.  And the HTTP spec very clearly *says* that it 
doesn't matter.  Folded headers are allowed, but they don't *add* any 
functionality.  So why allow it?  In those cases where you are 
interfacing with something that allows folded headers, they would have 
to be normalized; but most Python frameworks don't allow folded headers 
(at least intentionally).

I don't know if it would make a big difference if headers could be 
folded.  But there should be *some* use case for it if it were allowed.

>>>6.  The "write()" callable is important; it should not be deprecated
>>>or in some other way made a poor stepchild of the iterable.
>>
>>But it *is* one.  The presence of the 'write()' facility significantly 
>>increases the implementation complexity for middleware and server 
>>authors.  If it weren't necessary to support existing streaming APIs, it 
>>wouldn't exist.
> 
> 
> But supporting streaming APIs is an important consideration, from the
> point of view of authors actually writing code against a framework.
> It should be a peer methodology (or completely removed).

It effectively is a peer methodology.  It's part of the standard and it 
will work with any server; it's not optional.  The language Phillip 
wants to use is simply to encourage authors to prefer the iterable if 
that is an option.

> Again, WSGI is a very general mechanism, which should provide
> mechanism, not enforce policy.  That's the only way to get it widely
> accepted in all the server and framework projects.  If you don't like
> the streaming model, write editorials about it, but don't try to
> cripple other people's software.

There's no crippling, it is specifically allowed for.  It's not the 
primary interface that frameworks require, so Phillip wants to encourage 
those framework to use the iterable when they can.

For instance, in Webware the response object has a flush method.  When 
that is called, the accumulated response will have to be written out via 
the write method.  But in most cases a response is never flushed, it is 
cached completely until the request is over, and the whole page is sent 
at once.  The language is there to encourage someone to go to the extra 
length to return an iterable in the common case, instead of doing the 
easier thing and always using write.

Note that streaming can be implemented with the iterator interface. 
It's just a different streaming that wouldn't be compatible with all 
current frameworks.  If you aren't streaming then there's no real 
difference between the two, except that the iterator gives the server 
more leeway in implementation.

-- 
Ian Bicking  /  ianb at colorstudy.com  /  http://blog.ianbicking.org


More information about the Web-SIG mailing list