Python WSGI中间件是否可以修改请求主体,然后将其传递?

Python WSGI中间件是否可以修改请求主体,然后将其传递?,python,python-3.x,wsgi,Python,Python 3.x,Wsgi,我试图编写一个中间件,当它在主体中找到一个“\u method”参数时,将POST请求重写为另一个方法。互联网上有人写了这段代码: from werkzeug import Request class MethodRewriteMiddleware(object): def __init__(self, app, input_name='_method'): self.app = app self.input_name = input_name

我试图编写一个中间件,当它在主体中找到一个“\u method”参数时,将POST请求重写为另一个方法。互联网上有人写了这段代码:

from werkzeug import Request

class MethodRewriteMiddleware(object):
    def __init__(self, app, input_name='_method'):
        self.app = app
        self.input_name = input_name

    def __call__(self, environ, start_response):
        request = Request(environ)

        if self.input_name in request.form:
            method = request.form[self.input_name].upper()

            if method in ['GET', 'POST', 'PUT', 'DELETE']:
                environ['REQUEST_METHOD'] = method

        return self.app(environ, start_response)
据我所知,代码解析表单,检索一个可能的“\u method”参数,如果找到该参数并将其列入白名单,它将覆盖当前方法。它可以很好地处理删除请求,并且可以毫无问题地重写方法。然而,当我尝试发送一个常规的、未重写的帖子时,这个中间件会使整个应用程序挂起。我最好的猜测是,由于我在中间件中访问了主体,因此主体不再可用于应用程序,因此它将永远挂起。但是,这似乎不会影响重写的请求,因此代码最深的代码路径(检查白名单)工作正常,但另一个代码路径正在以某种方式破坏/阻止请求

我不认为这有什么关系,但我正在一个Flask应用程序上安装这个中间件

编辑:我认为试图从Flask中的处理程序访问
请求是阻塞。Flask内部是否使用互斥锁或类似的东西


我甚至不知道如何调试它。

environ
是一个带有wsgi的字典。input
键是一个流对象。手动方法是读取数据,进行任何更改,然后在
环境
字典中创建一个新字符串来替换旧流。下面的示例(没有任何错误处理或其他重要内容)允许您使用请求主体:

def __call__(self, environ, start_response):
    body = environ['wsgi.input'].read()
    ... do stuff to body ...
    new_stream = io.ByteIO(modified_body)
    environ['wsgi.input'] = new_stream
    return self.app(environ, start_response)

尝试仅使用flask导入请求中的
和flasks请求对象。您可以通过不使用werkzeug来验证您的假设,而是根据您自己的环境编写相关查询字符串解析代码。这应该不难(cgi模块有帮助),然后你可以确定你没有触摸身体。或者更好地使用shallow参数来请求。顺便说一句,你的问题是误导性的,因为唯一的答案是“是的,当然”。您可以在WSGI中对传递的参数执行任何您想执行的操作,如果您在传递这些参数(或完全新颖的参数)时仍然遵循WSGI,这对您有好处。你关心的只是werkzeug的参与。如果请求内容的大小非常大,这将耗尽内存使用。处理此问题的WSGI组件库可以更智能地执行此操作,如果超过某个大小,则会将内容写入文件,然后将类似文件的对象传递给该文件。最好使用现有的一个已经这样做的库。我知道Paste或WebOb有它的功能,但Werkzeug也可以。