【发布时间】:2017-02-28 22:07:16
【问题描述】:
问题说明: 在我尝试从 Chrome 浏览器访问不存在的文件后,我在 Flask 上的 Web 服务器未处理 HTTP 请求。当 Chrome 关闭或访问确实存在的页面时,会立即处理积压的 HTTP 请求。
影响:网络服务器可用性较差。
问题:为什么会发生这种情况以及如何在不以线程模式运行 Flask 的情况下修复它?
我在网上找到的最接近的帖子是:github.com/pallets/flask/issues/2188 但找不到完全相同的问题和解决方案。期待您的想法 - 非常感谢您的帮助!
主要假设: Chrome 没有读取 404 响应的所有内容,Flask 正在等待读取所有内容
详情:
重现问题的步骤:
1) 运行最小的 Flask 应用程序 (http://flask.pocoo.org/docs/0.12/quickstart/):
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
app.run()
- 在 хттп://127.0.0.1:5000/ 上运行(按 CTRL+C 退出)
2) 验证您在浏览器或 curl 中收到“Hello world”响应:
curl -v localhost:5000/
3) 在 Chrome 中转到 localhost:5000/pagethatdoesnotexists 在浏览器中观察 Not Found 错误
4) 重复 curl -v localhost:5000/ 命令
观察连接已建立但未收到响应 例如:
curl -v 本地主机:5000/ * 尝试 ::1... * 连接失败 * 连接到 ::1 端口 5000 失败:连接被拒绝 * 尝试 127.0.0.1... * 连接到 localhost (127.0.0.1) 端口 5000 (#0)
GET / HTTP/1.1 主机:本地主机:5000 用户代理:curl/7.49.0 接受:/
5) 在 Chrome 中转到存在的页面或关闭 Chrome
观察对 curl 的即时响应:
- HTTP 1.0,假设在正文之后关闭
- 关闭连接 0 你好,世界!
可能需要多次尝试才能重现该问题。通常发生 10 次中的 8 次以上
其他信息:
1) 我可以使用 Safari 或 telnet 或 python 脚本代替 curl - 同样的问题
2) Safari 不会产生问题,Chrome 会产生问题
3) 尝试通过发送与 Chrome 完全相同的 http 请求来模仿 Chrome,但无法重现该问题。 Chrome 可能会做其他事情。
4) 当我在线程模式下运行 Flask(使用不同的线程处理每个请求)时,问题就消失了。
5) 版本:
Chrome 版本 56.0.2924.87(64 位)
Python 3.5.2 |Anaconda 4.1.1(64 位)| (默认,2016 年 7 月 2 日,17:53:06) [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] 在linux上
flask.版本 '0.11.1'
6) 问题也在 AWS Ubuntu 生产服务器机器上重现
7) 尝试在 404 http 响应中发送自定义标头,但没有成功
@app.errorhandler(404)
def page_not_found(e):
# return render_template('404.html'), 404
resp = make_response(render_template('404.html'), 404)
# resp.headers['Connection'] = 'close'
resp.headers['Cache-Control'] = 'no-cache, no-store'
return resp
更新
我能够在没有 404 错误的情况下重现该问题,只需来自 Chrome 的正常 http 请求。 Flask 日志中没有观察到错误。
这里是video with the problem demonstration
另一件有趣的事 - 如果在 Chrome 浏览器中使用隐身窗口,则不会观察到问题。然而,在正常模式下清除缓存并不能解决问题。
【问题讨论】:
标签: python google-chrome http flask