我正在尝试编写一个中间件,当它在正文中找到“_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应用程序之上。
编辑:我认为尝试从Flask中的处理程序访问request
是阻止。 Flask是否在内部使用互斥量或类似内容?
我甚至不确定如何调试它。
答案 0 :(得分:0)
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)