这是一个 Flask 应用程序,可以从命令行或通过 Apache/WSGI 运行:
import flask
app = flask.Flask(__name__)
LENGTH = 1000000 # one million
@app.route('/', methods=['HEAD'])
def head():
return 'x' * LENGTH # response body isn't actually sent
@app.route('/', methods=['GET'])
def get():
import random
return ''.join(str(random.randint(0,9)) for x in range(LENGTH))
if __name__ == '__main__':
app.run() # from command-line
else:
application = app # via Apache and WSGI
也就是说,这个应用程序返回一百万个随机数字。 GET 请求需要花费相当多的时间,但 HEAD 请求应该能够几乎立即返回。这当然是一个说明性的例子;真实的应用程序会涉及大型响应,这些响应对于 GET 请求生成起来很慢,但也具有可以通过 HEAD 请求快速查询的预先确定的大小。 (另一种情况:我尝试将请求重定向到预签名的 Amazon S3 URL,该 URL 必须针对 HEAD 和 GET 方法进行不同的签名。)
问题 #1) 当我从命令行运行 Flask 应用程序时,HEAD 请求会激活head
功能符合预期;但是当我通过 Apache/WSGI 运行它时,它会激活get
功能。这是为什么,我该如何解决它以获得我想要的行为?
问题#2)为什么我不能返回,而不是为 HEAD 请求创建一个虚拟响应(分配一堆内存)app.make_response('', 200, {'Content-Length':LENGTH})
?
我的猜测是,这些是由善意的尝试引起的,目的是确保 HEAD 请求应始终与相应的 GET 一致。所以:
猜测 #1) Apache 或 WSGI 正在内部将 HEAD 重写为 GET。
猜测#2) Flask 不信任我手动设置 Content-Length 标头,并用响应正文的实际长度重写它......即使对于 HEAD 请求,实际上它应该是空的。
我误解了什么吗?有关如何更快地处理 HEAD 请求的任何建议,理想情况下无需缓慢生成仅用于设置 Content-Length 标头的大型响应正文?