我正在Flask应用程序中实现一个端点,该端点接收HTTP请求的集合,并返回相应HTTP响应的集合。为了做到这一点,我需要我的端点调用其他端点以构造结果。但是,由于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,而这种方法忽略了这些标头和cookie。此外,“ before_request”和“ after_request”处理程序中的代码不会自动调用
运行该应用程序的多个实例。这将解决问题,但会使我的服务遭受非常简单的DoS攻击。如果我有X个实例在运行,那么攻击者所需要做的就是用X个不同的请求击中我的服务,从而导致死锁。
谢谢你。
发生这种情况是因为您正在使用flask devserver。它不是用于生产。在生产环境中,您将使用带有或不带有Web服务器层(NGINX,Apache等)的应用程序服务器(uWSGI,GUnicorn,Tornado等)来代理/平衡与受保护的工人的连接(不是完全,而是在一个可以接受来自DoS攻击的很多环境)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句