aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/wsgiref/validate.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/wsgiref/validate.py')
-rw-r--r--Lib/wsgiref/validate.py59
1 files changed, 35 insertions, 24 deletions
diff --git a/Lib/wsgiref/validate.py b/Lib/wsgiref/validate.py
index 04a893d7c61..49eaa514cc5 100644
--- a/Lib/wsgiref/validate.py
+++ b/Lib/wsgiref/validate.py
@@ -98,7 +98,7 @@ Some of the things this checks:
- That it is not a string (it should be a list of a single string; a
string will work, but perform horribly).
- - That .next() returns a string
+ - That .__next__() returns a string
- That the iterator is not iterated over until start_response has
been called (that can signal either a server or application
@@ -113,7 +113,6 @@ __all__ = ['validator']
import re
import sys
-from types import DictType, StringType, TupleType, ListType
import warnings
header_re = re.compile(r'^[a-zA-Z][a-zA-Z0-9\-_]*$')
@@ -128,6 +127,12 @@ def assert_(cond, *args):
if not cond:
raise AssertionError(*args)
+def check_string_type(value, title):
+ if type (value) is str:
+ return value
+ raise AssertionError(
+ "{0} must be of type str (got {1})".format(title, repr(value)))
+
def validator(application):
"""
@@ -189,22 +194,23 @@ class InputWrapper:
self.input = wsgi_input
def read(self, *args):
- assert_(len(args) <= 1)
+ assert_(len(args) == 1)
v = self.input.read(*args)
- assert_(type(v) is type(""))
+ assert_(type(v) is bytes)
return v
- def readline(self):
- v = self.input.readline()
- assert_(type(v) is type(""))
+ def readline(self, *args):
+ assert_(len(args) <= 1)
+ v = self.input.readline(*args)
+ assert_(type(v) is bytes)
return v
def readlines(self, *args):
assert_(len(args) <= 1)
lines = self.input.readlines(*args)
- assert_(type(lines) is type([]))
+ assert_(type(lines) is list)
for line in lines:
- assert_(type(line) is type(""))
+ assert_(type(line) is bytes)
return lines
def __iter__(self):
@@ -223,7 +229,7 @@ class ErrorWrapper:
self.errors = wsgi_errors
def write(self, s):
- assert_(type(s) is type(""))
+ assert_(type(s) is str)
self.errors.write(s)
def flush(self):
@@ -242,7 +248,7 @@ class WriteWrapper:
self.writer = wsgi_writer
def __call__(self, s):
- assert_(type(s) is type(""))
+ assert_(type(s) is bytes)
self.writer(s)
class PartialIteratorWrapper:
@@ -265,10 +271,12 @@ class IteratorWrapper:
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
assert_(not self.closed,
"Iterator read after closed")
- v = self.iterator.next()
+ v = next(self.iterator)
+ if type(v) is not bytes:
+ assert_(False, "Iterator yielded non-bytestring (%r)" % (v,))
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")
@@ -288,7 +296,7 @@ class IteratorWrapper:
"Iterator garbage collected without being closed")
def check_environ(environ):
- assert_(type(environ) is DictType,
+ assert_(type(environ) is dict,
"Environment is not of the right type: %r (environment: %r)"
% (type(environ), environ))
@@ -315,11 +323,11 @@ def check_environ(environ):
if '.' in key:
# Extension, we don't care about its type
continue
- assert_(type(environ[key]) is StringType,
+ assert_(type(environ[key]) is str,
"Environmental variable %s is not a string: %r (value: %r)"
% (key, type(environ[key]), environ[key]))
- assert_(type(environ['wsgi.version']) is TupleType,
+ assert_(type(environ['wsgi.version']) is tuple,
"wsgi.version should be a tuple (%r)" % (environ['wsgi.version'],))
assert_(environ['wsgi.url_scheme'] in ('http', 'https'),
"wsgi.url_scheme unknown: %r" % environ['wsgi.url_scheme'])
@@ -365,8 +373,7 @@ def check_errors(wsgi_errors):
% (wsgi_errors, attr))
def check_status(status):
- assert_(type(status) is StringType,
- "Status must be a string (not %r)" % status)
+ status = check_string_type(status, "Status")
# Implicitly check that we can turn it into an integer:
status_code = status.split(None, 1)[0]
assert_(len(status_code) == 3,
@@ -380,16 +387,18 @@ def check_status(status):
% status, WSGIWarning)
def check_headers(headers):
- assert_(type(headers) is ListType,
+ assert_(type(headers) is list,
"Headers (%r) must be of type list: %r"
% (headers, type(headers)))
header_names = {}
for item in headers:
- assert_(type(item) is TupleType,
+ assert_(type(item) is tuple,
"Individual headers (%r) must be of type tuple: %r"
% (item, type(item)))
assert_(len(item) == 2)
name, value = item
+ name = check_string_type(name, "Header name")
+ value = check_string_type(value, "Header value")
assert_(name.lower() != 'status',
"The Status header cannot be used; it conflicts with CGI "
"script, and HTTP status is not given through headers "
@@ -405,11 +414,13 @@ def check_headers(headers):
% (value, bad_header_value_re.search(value).group(0)))
def check_content_type(status, headers):
+ status = check_string_type(status, "Status")
code = int(status.split(None, 1)[0])
# @@: need one more person to verify this interpretation of RFC 2616
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
NO_MESSAGE_BODY = (204, 304)
for name, value in headers:
+ name = check_string_type(name, "Header name")
if name.lower() == 'content-type':
if code not in NO_MESSAGE_BODY:
return
@@ -419,14 +430,14 @@ def check_content_type(status, headers):
assert_(0, "No Content-Type header found in headers (%s)" % headers)
def check_exc_info(exc_info):
- assert_(exc_info is None or type(exc_info) is type(()),
+ assert_(exc_info is None or type(exc_info) is tuple,
"exc_info (%r) is not a tuple: %r" % (exc_info, type(exc_info)))
# More exc_info checks?
def check_iterator(iterator):
- # Technically a string is legal, which is why it's a really bad
+ # Technically a bytestring is legal, which is why it's a really bad
# idea, because it may cause the response to be returned
# character-by-character
- assert_(not isinstance(iterator, str),
+ assert_(not isinstance(iterator, (str, bytes)),
"You should not return a string as your application iterator, "
- "instead return a single-item list containing that string.")
+ "instead return a single-item list containing a bytestring.")