我正在尝试编写一个中间件,当它在正文中找到“_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)
据我了解代码,它解析表单,检索可能的“_method”参数,如果找到并列入白名单,它将覆盖当前方法。它适用于 DELETE 请求,并且可以毫无问题地重写该方法。但是,当我尝试发送常规的、未重写的 POST 时,此中间件会使整个应用程序挂起。我最好的猜测是,由于我在中间件中访问了主体,主体不再可用于应用程序,因此它永远挂起。但是,这似乎不会影响重写的请求,因此代码最深的代码路径(检查白名单)正常工作,但其他代码路径以某种方式破坏/阻止请求。
我认为这无关紧要,但我正在将这个中间件安装在 Flask 应用程序之上。
编辑:我想尝试访问
request
来自 Flask 中的处理程序正在阻塞。 Flask 是否在内部使用互斥锁或类似的东西?我什至不确定如何调试它。
最佳答案
environ
是一本带有 wsgi.input
的字典键是一个流对象。手动执行所需操作的方法是读取数据,进行任何更改,然后创建一个新字符串来替换 environ
中的旧流。字典。下面的示例(没有任何错误处理或其他重要事项)允许您使用请求正文:
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)
关于python - WSGI 中间件可以修改请求体然后传递它吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31620957/