How to handle "413: Request Entity Too Large" in python flask server
Flask is closing the connection, you can set an error handler for the 413 error:
@app.errorhandler(413)def request_entity_too_large(error): return 'File Too Large', 413
Now the client should get a 413 error, note that I didn't test this code.
Update:
I tried recreating the 413 error, and I didn't get a ConnectionError exception.
Here's a quick example:
from flask import Flask, requestapp = Flask(__name__)app.config['MAX_CONTENT_LENGTH'] = 1024@app.route('/post', methods=('POST',))def view_post(): return request.dataapp.run(debug=True)
After running the file, I used the terminal to test requests and sending large data:
>>> import requests>>> r = requests.post('http://127.0.0.1:5000/post', data={'foo': 'a'})>>> r<Response [200]>>>> r = requests.post('http://127.0.0.1:5000/post', data={'foo': 'a'*10000})>>> r<Response [413]>>>> r.status_code413>>> r.content'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n<title>413 Request Entity Too Large</title>\n<h1>Request Entity Too Large</h1>\n<p>The data value transmitted exceeds the capacity limit.</p>\n'
As you can see, we got a response from flask 413 error and requests didn't raise an exception.
By the way I'm using:
- Flask: 0.10.1
- Requests: 2.0.0
RFC 2616, the specification for HTTP 1.1, says:
10.4.14 413 Request Entity Too Large
The server is refusing to process a request because the request
entity is larger than the server is willing or able to process. The
server MAY close the connection to prevent the client from continuing the request.If the condition is temporary, the server SHOULD include a Retry-
After header field to indicate that it is temporary and after what
time the client MAY try again.
This is what's happening here: flask is closing the connection to prevent the client from continuing the upload, which is giving you the Broken pipe
error.
Based on this github issue answers (https://github.com/benoitc/gunicorn/issues/1733#issuecomment-377000612)
@app.before_requestdef handle_chunking(): """ Sets the "wsgi.input_terminated" environment flag, thus enabling Werkzeug to pass chunked requests as streams. The gunicorn server should set this, but it's not yet been implemented. """ transfer_encoding = request.headers.get("Transfer-Encoding", None) if transfer_encoding == u"chunked": request.environ["wsgi.input_terminated"] = True