From 3f2f7f72a73caf087066c75d2e2b6e5ed908d34d Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Fri, 29 Jun 2012 09:26:09 +0200 Subject: fix more bytes related issues not covered by test.py * applications returned errors as str instead of bytes * filters documentation updated with bytes * various filters expecting str where bytes are passed * escape_string also needs to use bytes.isalnum instead of str.isalnum * middlewares injecting str where bytes are expected --- wsgitools/filters.py | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) (limited to 'wsgitools/filters.py') diff --git a/wsgitools/filters.py b/wsgitools/filters.py index 6f90903..882a0bf 100644 --- a/wsgitools/filters.py +++ b/wsgitools/filters.py @@ -12,6 +12,8 @@ import time import gzip import io +from wsgitools.internal import str2bytes + __all__.append("CloseableIterator") class CloseableIterator: """Concatenating iterator with close attribute.""" @@ -122,15 +124,15 @@ class BaseWSGIFilter: """For each string that is either written by the C{write} callable or returned from the wrapped wsgi application this method is invoked. It must return a string. - @type data: str - @rtype: str + @type data: bytes + @rtype: bytes """ return data def append_data(self): """This function can be used to append data to the response. A list of strings or some kind of iterable yielding strings has to be returned. The default is to return an empty list. - @rtype: gen([str]) + @rtype: gen([bytes]) """ return [] def handle_close(self): @@ -152,7 +154,7 @@ class WSGIFilterMiddleware: def __call__(self, environ, start_response): """wsgi interface @type environ: {str, str} - @rtype: gen([str]) + @rtype: gen([bytes]) """ assert isinstance(environ, dict) reqfilter = self.filterclass() @@ -196,7 +198,7 @@ class WSGIFilterMiddleware: # default arguments. Also note that neither ' nor " are considered printable. # For escape_string to be reversible \ is also not considered printable. def escape_string(string, replacer=list(map( - lambda i: chr(i) if chr(i).isalnum() or + lambda i: chr(i) if str2bytes(chr(i)).isalnum() or chr(i) in '!#$%&()*+,-./:;<=>?@[]^_`{|}~ ' else r"\x%2.2x" % i, range(256)))): @@ -267,11 +269,7 @@ class RequestLogWSGIFilter(BaseWSGIFilter): self.status = status.split()[0] return status def filter_data(self, data): - """BaseWSGIFilter interface - @type data: str - @rtype: str - """ - assert isinstance(data, str) + assert isinstance(data, bytes) self.length += len(data) return data def handle_close(self): @@ -306,30 +304,31 @@ class TimerWSGIFilter(BaseWSGIFilter): def creator(cls, pattern): """Returns a function creating L{TimerWSGIFilter}s with a given pattern beeing a string of exactly eight bytes. - @type pattern: str + @type pattern: bytes """ return lambda:cls(pattern) - def __init__(self, pattern="?GenTime"): + def __init__(self, pattern=b"?GenTime"): """ @type pattern: str """ BaseWSGIFilter.__init__(self) + assert isinstance(pattern, bytes) self.pattern = pattern self.start = time.time() def filter_data(self, data): """BaseWSGIFilter interface - @type data: str - @rtype: str + @type data: bytes + @rtype: bytes """ if data == self.pattern: - return "%8.3g" % (time.time() - self.start) + return str2bytes("%8.3g" % (time.time() - self.start)) return data __all__.append("EncodeWSGIFilter") class EncodeWSGIFilter(BaseWSGIFilter): """Encodes all body data (no headers) with given charset. @note: This violates the wsgi standard as it requires unicode objects - whereas wsgi mandates the use of str. + whereas wsgi mandates the use of bytes. """ @classmethod def creator(cls, charset): @@ -347,7 +346,7 @@ class EncodeWSGIFilter(BaseWSGIFilter): def filter_data(self, data): """BaseWSGIFilter interface @type data: str - @rtype: str + @rtype: bytes """ return data.encode(self.charset) def filter_header(self, header, value): @@ -414,10 +413,6 @@ class GzipWSGIFilter(BaseWSGIFilter): headers.append(("Content-encoding", "gzip")) return headers def filter_data(self, data): - """BaseWSGIFilter interface - @type data: str - @rtype: str - """ if not self.compress: return data self.gzip.write(data) @@ -428,9 +423,6 @@ class GzipWSGIFilter(BaseWSGIFilter): self.sio.seek(0) return data def append_data(self): - """BaseWSGIFilter interface - @rtype: [str] - """ if not self.compress: return [] self.gzip.close() -- cgit v1.2.3