【问题标题】:Sending a flask request within a flask request在烧瓶请求中发送烧瓶请求
【发布时间】:2014-07-23 13:55:16
【问题描述】:

我正在我的 Flask 应用程序中实现一个端点,该端点接收一组 HTTP 请求,并返回一组相应的 HTTP 响应。为了实现这一点,我需要我的端点调用其他端点来构造结果。但是,由于 Flask 在处理原始请求时处于阻塞状态,因此无法处理嵌套请求,导致应用程序陷入死锁。

有什么方法可以在flask中的请求中以不会导致死锁的方式发出请求?

我包含了我的一段代码,我认为它应该足以说明问题而不会让你不知所措。如果您想查看更多内容,请告诉我,我会分享。

from requests import Session, Request

def split(request):
    multipart = request.stream.read()
    boundary = request.content_type.split(';')[1]
    prefix = ' boundary"'
    suffix = '"'
    delimiter = '--%s' % boundary[len(prefix)+1:-len(suffix)]
    subrequests = [s.lstrip() for s in multipart.split(delimiter)]
    for sub in subrequests:
        status_line, _, more_lines = sub.partition('\n')
        method, path, version = status_line.split()
        headers, _, body = more_lines.partition('\n\n')
        url = 'http://localhost:3000' + path
        return Request(method, url, headers=headers, data=body)

@app.route('/batch', methods=["GET", "POST"])
def batch():
    subrequests = split(request)
    session = Session()
    responses = []
    for sub in subrequests:
        response.append(s.send(sub.prepare())) # Deadlock!

我认为有两个候选解决方案并不令人满意:

  1. 不要发出完整的请求。相反,只需调用映射到感兴趣的端点 (url_for) 的函数。我对这种方法不满意,因为嵌套请求有自己的标头和 cookie,这种方法会忽略它们。此外,“before_request”和“after_request”处理程序中的代码不会被自动调用

  2. 运行应用程序的多个实例。这将解决问题,但会将我的服务暴露给非常简单的 DoS 攻击。如果我有 X 个实例在运行,那么攻击者需要做的就是用 X 个不同的请求攻击我的服务,从而导致死锁。

谢谢。

【问题讨论】:

    标签: python web-services python-2.7 flask webserver


    【解决方案1】:

    知道内部烧瓶服务器不是生产就绪的,当仅用于开发时,将 threaded=true 参数传递给 app.run。

    app.run(debug=True, threaded=True)
    

    【讨论】:

      【解决方案2】:

      发生这种情况是因为您使用的是烧瓶开发服务器。它用于生产用途。 在生产环境中,您将使用一个应用程序服务器(uWSGI、GUnicorn、Tornado 等),有或没有一个网络服务器层(NGINX、Apache 等)来代理/平衡与保护工作人员的连接(不完全,但在一个很多环境都是可以接受的)免受 DoS 攻击。

      【讨论】:

      • 谢谢。我目前正在开发和使用我的开发服务器。但是,如果我理解您的意思,在生产环境中让一名工人被其他工人阻止是可以接受的吗?应用服务器如何缓解这种情况?
      • @gilsho 没有。这是不可接受的,应用程序服务器是多线程的,并且分叉多个进程(或使用其他技术)以并行运行更多请求。您面临的问题仅发生在 devserver 上,因为它在单个进程/线程中运行,一次管理一个请求。
      • 抱歉,我的问题可能不够简洁:在使用 GUnicorn、uWSGI 等应用程序服务器为我的应用程序提供服务的生产环境中,让一个工作人员被其他工作人员阻止是否可以接受?跨度>
      • @gilsho 没有一个简单的答案。 :) 如果您使用像龙卷风这样的应用程序服务器(我在 gunicorn 上不确定),您的工作人员在等待 http 请求的响应时不会被阻止服务其他请求。 Tornado 以异步方式处理此问题。希望这可以帮助。 :)
      猜你喜欢
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      • 2018-08-22
      • 2016-04-21
      • 2017-06-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多