【发布时间】: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!
我认为有两个候选解决方案并不令人满意:
不要发出完整的请求。相反,只需调用映射到感兴趣的端点 (url_for) 的函数。我对这种方法不满意,因为嵌套请求有自己的标头和 cookie,这种方法会忽略它们。此外,“before_request”和“after_request”处理程序中的代码不会被自动调用
运行应用程序的多个实例。这将解决问题,但会将我的服务暴露给非常简单的 DoS 攻击。如果我有 X 个实例在运行,那么攻击者需要做的就是用 X 个不同的请求攻击我的服务,从而导致死锁。
谢谢。
【问题讨论】:
标签: python web-services python-2.7 flask webserver