解决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

所以,这个方法也不行