在烧瓶请求中发送烧瓶请求

时间:2014-06-03 09:30:00

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

我在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个不同的请求命中我的服务以导致死锁。

  3. 谢谢。

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

这会导致您使用flask devserver。用于生产的。 在生产环境中,您可以使用应用程序服务器(uWSGI,GUnicorn,Tornado,...),无论是否有网络服务器层(NGINX,Apache,...)来代理/平衡与保护工作人员的连接(不是完全但在来自DoS攻击的很多环境。