-# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
-# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
-# Also licenced under the Apache License, 2.0: http://opensource.org/licenses/apache2.0.php
-# Licensed to PSF under a Contributor Agreement
+# (c) 2005 Ian Bicking and contributors; written for Paste
+# Licensed under the MIT license:
+# http://www.opensource.org/licenses/mit-license.php Also licenced under the
+# Apache License, 2.0: http://opensource.org/licenses/apache2.0.php Licensed to
+# PSF under a Contributor Agreement
Middleware to check for obedience to the WSGI specification.
METADATA_TYPE = (str, bytes)
Raised in response to WSGI-spec-related warnings
def middleware(application, global_conf=None):
def __init__(self, wsgi_input):
assert 0, "input.close() must not be called"
def __init__(self, wsgi_errors):
assert 0, "errors.close() must not be called"
def __init__(self, wsgi_writer):
def __init__(self, wsgi_iterator):
# We want to make sure __iter__ is called
def __init__(self, wsgi_iterator, check_start_response):
if self.check_start_response is not None:
assert self.check_start_response, (
- "The application returns and we started iterating over its body, but start_response has not yet been called")
+ "The application returns and we started iterating over its"
+ " body, but start_response has not yet been called")
self.check_start_response = None
assert isinstance(v, bytes), (
"Iterator %r returned a non-%r object: %r"
"Iterator garbage collected without being closed")
assert type(environ) is dict, (
"Environment is not of the right type: %r (environment: %r)"
# @@: these need filling out:
if environ['REQUEST_METHOD'] not in (
- 'GET', 'HEAD', 'POST', 'OPTIONS','PUT','DELETE','TRACE'):
+ 'GET', 'HEAD', 'POST', 'OPTIONS','PUT','DELETE','TRACE'):
"Unknown REQUEST_METHOD: %r" % environ['REQUEST_METHOD'],
"SCRIPT_NAME cannot be '/'; it should instead be '', and "
"PATH_INFO should be '/'")
for attr in ['read', 'readline', 'readlines', '__iter__']:
assert hasattr(wsgi_input, attr), (
"wsgi.input (%r) doesn't have the attribute %s"
for attr in ['flush', 'write', 'writelines']:
assert hasattr(wsgi_errors, attr), (
"wsgi.errors (%r) doesn't have the attribute %s"
- assert type(status) in METADATA_TYPE
+ assert type(status) in METADATA_TYPE, (
"Status must be a %s (not %r)" % (METADATA_TYPE, status))
# Implicitly check that we can turn it into an integer:
status_code = status.split(None, 1)
"followed by a single space and a status explanation"
assert type(headers) is list, (
"Headers (%r) must be of type list: %r"
"Bad header value: %r (bad char: %r)"
% (str_value, bad_header_value_re.search(str_value).group(0)))
def check_content_type(status, headers):
code = int(status.split(None, 1))
# @@: need one more person to verify this interpretation of RFC 2616
if code not in NO_MESSAGE_BODY:
assert 0, "No Content-Type header found in headers (%s)" % headers
assert exc_info is None or type(exc_info) is tuple, (
"exc_info (%r) is not a tuple: %r" % (exc_info, type(exc_info)))
# Technically a bytes is legal, which is why it's a really bad
# idea, because it may cause the response to be returned
"You should not return a string as your application iterator, "
"instead return a single-item list containing bytes.")
def make_middleware(application, global_conf):
# @@: global_conf should be taken out of the middleware function,