python - 为什么 Apache/WSGI 将 HEAD 映射到 GET?如何在 Flask 中加速 HEAD?

标签 python http flask wsgi

这是一个可以从命令行或通过 Apache/WSGI 运行的 Flask 应用程序:

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,对于 HEAD 和 GET 方法,这些 URL 必须进行不同的签名。)

问题 #1)当我从命令行运行 Flask 应用程序时,HEAD 请求会按预期激活 head 函数;但是当我通过 Apache/WSGI 运行它时,它会激活 get 函数。为什么会这样,我该如何解决它以获得我想要的行为?

问题 #2)为什么我不能返回 app.make_response('', 200, {'Content-Length':长度})?

我的猜测是,这些是出于善意的尝试,以确保 HEAD 请求应始终与相应的 GET 一致。所以:

猜测 #1)Apache 或 WSGI 在内部将 HEAD 重写为 GET。

猜测 #2)Flask 不相信我会手动设置 Content-Length header ,并用响应主体的实际长度重写它......即使对于 HEAD 请求,实际上这应该是空的.

我是不是误会了什么?关于如何能够更快地处理 HEAD 请求的任何建议,理想情况下不必缓慢生成仅用于设置 Content-Length header 的大型响应主体?

最佳答案

如前所述,为什么 mod_wsgi 将 HEAD 重新映射到 GET 的问题在以下内容中得到了很好的描述:

特别是,如该博客文章中所述,如果您设置了 Apache 输出过滤器,并且因此有可能需要从您的 WSGI 应用程序查看针对同一 URL 的 GET 或 HEAD 的相同输出,那么 mod_wsgi 将不会相信您的应用程序会做正确的事情,并且会将 HEAD 重新映射到 GET 以确保 Apache 输出过滤器能够正常工作。

如果您不关心您没有为 HEAD 请求返回与 GET 请求相同的响应 header ,从而违反了 HTTP RFC 指定的 HEAD 要求,那么只需确保您没有 Apache输出过滤器已配置,您可以随心所欲地破坏事物,因为 mod_wsgi 不会重新映射请求方法类型。

关于python - 为什么 Apache/WSGI 将 HEAD 映射到 GET?如何在 Flask 中加速 HEAD?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22443245/

相关文章:

pythonw 3.6.6 sys.stdout 在重新分配时不执行任何操作

python - Pandas 无需更换即可加入

python-3.x - 安排任务在未来某个时间点运行(架构)

python - Flask init-db 没有这样的命令

python - 如何使用 numpy 对 Floyd-Steinberg 的抖动算法进行矢量化?

python - 对制表符分隔的文件执行计算

http - 为什么 websocket 需要使用 HTTP 打开握手?为什么它不能是一个独立的协议(protocol)?

rest - 在 REST API 中,要获取资源,我应该在 url 中包含资源 ID 吗?

apache - apache 的最大 url 长度是多少?

javascript - 将存储在 S3 上的文件流式传输到客户端,而无需将其下载到 Flask 服务器