[Web-SIG] WSGI tests
Ian Bicking
ianb at colorstudy.com
Wed Sep 29 19:23:54 CEST 2004
Phillip J. Eby wrote:
> Actually, it just occurred to me that there *is* a legitimate test you
> can do for SCRIPT_NAME and PATH_INFO: at least *one* of them must be
> present and non-blank, because if you're at the site root, SCRIPT_NAME
> is empty and PATH_INFO has to be '/'. (Or the other way around, the CGI
> spec isn't clear on this, but Apache CGI puts the '/' in PATH_INFO.)
OK... I guess the root of a domain is an odd case, because I can't
imagine what the difference between SCRIPT_NAME="/", PATH_INFO="" or
SCRIPT_NAME="", PATH_INFO="/" would mean.
On further thought, I think it doesn't make sense for SCRIPT_NAME to be
"/". Because PATH_INFO must always start with a "/", SCRIPT_NAME must
be "" if there's any path (unless we get double /'s when reconstructing
the URL, which wouldn't be good). So I think I'm going to make the test
include SCRIPT_NAME != "/". The general case would say that SCRIPT_NAME
should not end with a /, but I don't feel 100% confident that that's
correct.
> Anyway, it's never valid to have both empty or missing, so you can:
>
> assert environ.get('SCRIPT_NAME') or environ.get('PATH_INFO')
>
> Also, if present and non-empty, both of these variables must *begin*
> with a '/', so it's more like:
>
> script_name = environ.get('SCRIPT_NAME','')
> path_info = environ.get('PATH_INFO','')
> assert not script_name or script_name.startswith('/')
> assert not path_info or path_info.startswith('/')
> assert script_name or path_info
Yes, the '/' tests were already in there.
>>> By the way, I found another issue with lint: IteratorWrapper doesn't
>>> close the original iterable if it had a close() method.
>>
>>
>> Fixed as well.
>
>
> Actually, no. Lint's iterator close() is still broken. You have to use
> close() on the *iterable*, not on iter(iterable). The two may be
> different objects, since an iterable may return a separate iterator object.
This was something I felt a little ambiguous about. I assume the server
always must iterate over iter(app_iter), it can't iterate over app_iter
directly. When using a "for" loop there's not much distinction, but if
you access the .next() methods directly there would be. Anyway, I'm a
little fuzzy when __iter__ gets called implicitly. I was suprised that
it seemed to get called twice when iterating with a simple for look, and
I had to add IteratorWrapper.__iter__.
> Also, pycgiwrapper returns None from __call__, when it should return an
> iterator. A simple way to fix that would be to just 'return [body]'
> after calling start_respsonse.
I've added a check in lint specifically for None or False for the
iterator; it would still fail implicitly before, but this way the error
should be better. I haven't tested pycgiwrapper yet, or some of the
other code I wrote before, so there might be other bugs in there (e.g.,
unnecessary use of write(), or returning None).
> I'm pretty much coming to the conclusion that WSGI is no longer
> "simple", alas. For it to actually be usable, there's going to have to
> be a reference library, as well as tests. I'm going to keep pecking
> away at your lint program, and eventually your other test facilities as
> well, so that I'll have something to test the reference library with. :)
The basic mechanics are still reasonably simple, but there's a lot of
smaller things to consider. So I don't think WSGI has become that much
more complicated, we've just come to appreciate complexities that were
there all along.
Also, should we be putting all of this code in a single repository?
--
Ian Bicking / ianb at colorstudy.com / http://blog.ianbicking.org
More information about the Web-SIG
mailing list