diff options
-rw-r--r-- | wsgitools/filters.py | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/wsgitools/filters.py b/wsgitools/filters.py index 1c7d03b..07675ba 100644 --- a/wsgitools/filters.py +++ b/wsgitools/filters.py @@ -388,3 +388,45 @@ class GzipWSGIFilter(BaseWSGIFilter): self.gzip.close() data = self.sio.getvalue() return [data] + +class ReusableWSGIInputFilter(BaseWSGIFilter): + """Make environ["wsgi.input"] readable multiple times. Although this is not + required by the standard it is sometimes desirable to read wsgi.input + multiple times. This filter will therefore replace that variable with a + StringIO instance which provides a seek method. + """ + @classmethod + def creator(cls, maxrequestsize): + """ + Returns a function creating ReusableWSGIInputFilters with desired + maxrequestsize being set. If there is more data than maxrequestsize is + available in wsgi.input the rest will be ignored. (It is up to the + adapter to eat this data.) + @type maxrequestsize int + @param maxrequestsize is the maximum number of bytes to store in the + StringIO + """ + return lambda:cls(maxrequestsize) + def __init__(self, maxrequestsize=65536): + """ReusableWSGIInputFilters constructor. + @type maxrequestsize int + @param maxrequestsize is the maximum number of bytes to store in the + StringIO, see creator + """ + BaseWSGIFilter.__init__(self) + self.maxrequestsize = maxrequestsize + + def filter_environ(self, environ): + """BaseWSGIFilter interface + @type environ: {str: str} + """ + + if isinstance(environ["wsgi.input"], StringIO): + return environ # nothing to be done + + # XXX: is this really a good idea? use with care + environ["wsgitools.oldinput"] = environ["wsgi.input"] + data = StringIO(environ["wsgi.input"].read(self.maxrequestsize)) + environ["wsgi.input"] = data + + return environ |