Some WSGI servers, e.g. Werkzeug, unconditionally attempt to iterate over the
application response, even for HEAD requests. If `None` is returned, then the
server will crash in this case, because it is not iterable. This commit alters
the behavior of `milla.Application` to return an empty string, which is
iterable and has the same effect of not sending a body.
When the application path info is empty (e.g. the WSGI script is mounted
somewhere other than the root), appending a trailing slash and redirecting
causes the new location to be calculated incorrectly. This is because the part
of the request URL before the application path is not taken into account, so
the new path always ends up being a literal `/`. This commit changes the
behavior of the `redir` function that is returned by
`milla.dispatch.routing.Router.resolve` to calculate the new path info
correctly in the redirect response.
If a controller callable returns a string, it needs to be wrapped in a
Response object. To determine if this is the case, the Application tests to
see if the returned object is an instance of `basestring`. Since `basestring`
doesn't exist in Python 3, only `str` is a valid return type.
Unfortunately, my way of testing whether the `basestring` type existed was
flawed. Instead of raising `NameError` when it doesn't exist,
`UnboundLocalError` (a subclass `NameError`) is *always* raised. Since the
exception handler sets `basestring` equal to `str` assuming this is Python 3,
most of the time this isn't a problem. If, however, the controller returns a
`unicode` object in Python 2, the `isinstance` call returns `False`, so the
response is not wrapped in a Response object.
Rather than try to reassign the `basestring` name, now we just use `_string`,
which will either be `basestring` (in Python 2) or `str` (in Python 3).
Apparently, the unit tests didn't cover this case...