Problem statement: my web server on Flask is not processing HTTP requests after I try to access non existing file from Chrome browser. When Chrome is shut down or accessing page that does exists, the backlog HTTP requests are processed at once.
Impact: web server availability is poor.
Question: why does it happen and how to fix it without running Flask in threaded mode?
The closest post I found online is this: github.com/pallets/flask/issues/2188
but could not find exactly the same problem and solution. Looking forward to your thoughts – thanks so much for your help!
Primary Hypothesis: Chrome does not read all content of the 404 response, and Flask is waiting all the content to be read
Steps to reproduce the problem:
1) run minimal Flask application (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()
- Running on хттп://127.0.0.1:5000/ (Press CTRL+C to quit)
2) verify you get ‘Hello world’ response in browser or curl:
curl -v localhost:5000/
3) in Chrome go to localhost:5000/pagethatdoesnotexists
observe Not Found error in the browser
4) repeat curl -v localhost:5000/ command
observe that connection is established but response is not received
curl -v localhost:5000/
* Trying ::1…
* Connection failed
* connect to ::1 port 5000 failed: Connection refused
* Trying 127.0.0.1…
* Connected to localhost (127.0.0.1) port 5000 (#0)
GET / HTTP/1.1
5) in Chrome go to the page that exists or shut down Chrome
observe immediate response to curl:
- HTTP 1.0, assume close after body < HTTP/1.0 200 OK < Content-Type: text/html; charset=utf-8 < Content-Length: 13 < Server:
Werkzeug/0.11.10 Python/3.5.1 < Date: Tue, 28 Feb 2017 21:44:20 GMT <
- Closing connection 0 Hello, World!
it may take more than one attempt to reproduce the problem. Typically happens >8 times out of 10
Other pieces of information:
1) instead of curl I can use Safari or telnet or a python script – same problem
2) Safari does not create the problem, which Chrome does
3) tried to mimic Chrome by sending exactly the same http request as Chrome does – but cannot reproduce the problem. Chrome probably does something else.
4) when I run Flask in threaded mode (handling each request with a different thread), the problem goes away.
Chrome Version 56.0.2924.87 (64-bit)
Python 3.5.2 |Anaconda 4.1.1 (64-bit)| (default, Jul 2 2016, 17:53:06)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
6) issue is also reproduced on AWS Ubuntu production server machine
7) tried sending custom headers in 404 http response with no luck
@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
I was able to reproduce the problem without 404 error, just with normal http requests from Chrome. There are no errors in Flask log observed.
Here is the video with the problem demonstration
Another interesting thing – if using incognito window in Chrome browser, the problem is not observed. Yet, clearing cache in normal mode Chrome does not solve the problem.
I’ve ran into the same problem twice.
The same environment: pure Flask (no reverse proxy), the simplest application.
After you’ve open URL with Chrome/Chromium — Flask will hang and won’t respond to other clients (curl, postman, firefox, python-request, ..).
Workaround for Chrome
Disable URL-prediction services in Chrome/Chromium (Actual names of options are on the screenshot)
Real solution (for Flask)
Comming soon — contributions are welcome! (most probably I will never resolve this).
Answered By – maxkoryukov
Answer Checked By – Senaida (Easybugfix Volunteer)