Flask中如何处理不符合HTTP标准的畸形API请求?
Flask中如何处理不符合HTTP标准的畸形API请求?
这个问题我之前也碰到过!核心原因是你试的那些钩子、装饰器都太晚了——Flask底层依赖的Werkzeug会在请求到达你的业务代码之前,先做HTTP标准校验,一旦发现请求行的方法或协议版本不符合规范,直接就返回400了,根本轮不到你的before_request、装饰器甚至原来的中间件执行。
要解决这个问题,我们必须在Werkzeug开始解析请求之前,就修正畸形的请求参数。具体来说,就是在WSGI中间件里修改请求的核心元数据,让它符合HTTP标准。
为什么之前的方案失效?
@before_request钩子、视图装饰器:这些都是Flask在请求被Werkzeug成功解析为request对象之后才触发的,一旦请求格式非法,Werkzeug直接返回400,根本到不了这些步骤。- 你之前的WSGI中间件:只是打印了请求信息,但没有修改核心的请求参数,所以Werkzeug还是会识别到畸形请求。
解决方案:修正WSGI中间件
我们需要修改中间件,在请求被Werkzeug处理前,修正environ字典里的请求方法和协议版本(这两个是Werkzeug校验的关键点):
from flask import Flask, request from functools import wraps app = Flask(__name__) class RequestMiddleware: def __init__(self, app): self.app = app def __call__(self, environ, start_response): # 修正请求方法为标准大写格式(兼容Get/get等变体) req_method = environ.get('REQUEST_METHOD', '') if req_method.lower() == 'get': environ['REQUEST_METHOD'] = 'GET' # 修正协议版本为标准格式(把http/1.1改成HTTP/1.1) proto = environ.get('SERVER_PROTOCOL', '') if proto == 'http/1.1': environ['SERVER_PROTOCOL'] = 'HTTP/1.1' print('修正后请求信息:', environ['REQUEST_METHOD'], environ['SERVER_PROTOCOL']) return self.app(environ, start_response) def RequestDecorator(view): @wraps(view) def decorated(*args, **kwargs): print('Decorator', args, kwargs) return view(*args, **kwargs) return decorated @app.before_request def RequestHook(): print('Before request: url: %s, path: %s' % (request.url, request.path)) # 应用修正后的中间件 app.wsgi_app = RequestMiddleware(app.wsgi_app) @app.route("/config.php", methods=["GET"]) @RequestDecorator def get_config(): return ("{}", 200) if __name__ == '__main__': app.run(debug=True)
关键逻辑说明
- 中间件的执行时机:这个中间件包裹在Flask的
wsgi_app外面,意味着它会在Werkzeug开始解析请求之前拿到原始的environ字典(WSGI标准中,environ包含了所有请求元数据)。 - 请求方法修正:把非标准的
Get/get统一转成大写GET,兼容游戏可能的写法变体。 - 协议版本修正:把小写的
http/1.1改成标准的HTTP/1.1,让Werkzeug能正常识别。
测试效果
当游戏发送Get /config.php http/1.1这个畸形请求时,中间件会先修正参数,Werkzeug就能正常解析请求,你的before_request钩子、装饰器、视图函数都会按预期执行,最终返回200而不是400。
如果游戏还有其他畸形请求的情况(比如请求行格式错误、头部格式问题等),可能需要直接读取wsgi.input中的原始请求数据,修正整个请求行后再重新构造environ,但针对你当前的问题,上面的方案已经足够解决。
备注:内容来源于stack exchange,提问作者lolbas
相关产品推荐
相关产品推荐

