解决flask路由调用函数的尴尬问题
背景
遇到一个问题,之前写了创建评估任务–调用扫描–结果提交漏洞这么一个功能,运行的时候发现创建完评估任务提交一个请求直接执行扫描,不扫完就没有return结果,所以造成了没扫描完不能成功创建评估任务的尴尬局面。
脚本的正常逻辑应该是提交请求–判断合法性–返回结果–执行扫描–提交漏洞
解决办法
先说最后解决的方法
1、最终解决办法–异步调用
参考:python调用异步函数执行
写个装饰器定义多线程函数,在扫描脚本前加装饰器。
scan函数能跟接收请求的svnaddr函数异步执行,这样也能达到先return再scan的效果
def myasync(f):
def wrapper(*args, **kwargs):
thr = Thread(target=f, args=args, kwargs=kwargs)
thr.start()
return wrapper
@app.route('/svnaddr', methods=['POST'])
def svnaddr():
if flag == False:
# 判断参数合法性
code = 1
message = str(taskid)+' create success !'
handleScan(taskid, repo, model, scantime, status)
return_info = {'code':code, 'message':message}
return jsonify(return_info)
# 扫描
@myasync
def handleScan(taskid, repo, model, scantime, status):
scan...
搞定!
2、错误方法–全局变量上下文引用
度娘告诉我的。。也许是我问问题的方式不对,这个思路完全误导我。思路是定义一个全局变量,路由接收到请求后传递给全局变量,下面写个scan函数调用这个全局变量
但是写了发现,路由执行完之后并不会接着执行下面的函数。。。下面是错误的写法
def handleScan(taskid, repo, model, scantime, status):
scan...
@app.route('/svnaddr', methods=['POST'])
def svnaddr():
get_request...
if __name__ == '__main__':
app.run(host='192.168.57.2',port=5001)
handleScan(taskid, repo, model, scantime, status)
3、try-finally
原理:无论是否执行try,最后都会执行finally
想法是在try里return,在finally里调用scan()
代码:
try:
return_info = {'code':code,'message':message}
return jsonify(return_info)
finally:
scan()
def scan():
print("hhh")
看上去可以,先执行try,在try块里return,再执行finally
跑了个测试脚本,嗯,可以,以为成功
但是在正式跑扫描脚本的时候发现其实还是先扫描再return了。
emmm,原因在这finally和return的执行顺序
执行顺序为:try块语句–finally语句–return,return永远最后执行,如果finally里有return就不会执行try里的return
所以,这个方法也不行