python - WSGI 中间件可以修改请求体然后传递它吗?

标签 python python-3.x wsgi

我正在尝试编写一个中间件,当它在正文中找到“_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/

相关文章:

python - 在 Django 中的 Linode Ubuntu 21.10 上运行的 Apache 2 出现 403 错误

python-3.x - 这段代码是什么意思? (训练测试拆分 Scikit Learn)

python - 连续目录名称 Python 3

python - 理解 eventlet.wsgi.server

python - Celery 任务状态取决于 CELERY_TASK_RESULT_EXPIRES

python - 如何显示 Django 中 ManyToMany 字段的值而不是 Id?

python - Intellij IDEA 中的 Quick documentation 和 Autopopup documentation 有什么区别?

python - 以下场景必须使用哪种 ZMQ 模式?

python - 调整CSV数据: appending cells to previous row,合并包含特定字符串的单元格

wsgi - 'pserve' 不适合在 nginx 后面为我的 Pyramid 应用程序提供生产用途吗?