hypercorn
hypercorn copied to clipboard
Issue when sending large payload (HTTP CODE 400 or 104)
Hi,
I'm faced up a weird behaviour when sending a large amount of data to hypercorn and flask. Here the steps to reproduce:
Generate the data file
dd if=/dev/urandom of=test.output bs=50M count=2
Start hypercorn
hypercorn app:app
Query
With curl:
curl -i -H 'Content-Length: 104857600' -X POST --data-binary "@test.output" http://localhost:8000/data
or a python code:
import requests requests.post("http://localhost:8000/data", files={"file": open('test.output', 'rb')})
With curl the output is :
HTTP/1.1 100
date: Fri, 04 Nov 2022 14:03:58 GMT
server: hypercorn-h11
HTTP/1.1 400
date: Fri, 04 Nov 2022 14:03:58 GMT
server: hypercorn-h11
Transfer-Encoding: chunked
With python client:
ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
The flask code is the following:
import logging
from time import strftime
from flask import Flask, request
app = Flask(__name__)
logger = logging.getLogger('bench')
logger.setLevel(logging.ERROR)
@app.route('/data', methods=["POST"])
def send_data():
"""Send large data."""
data = request.get_data()
return str(len(data)) + "\n"
@app.before_request
def before_request_func():
timestamp = strftime('[%Y-%m-%d %T %z]')
logger.error(f"{timestamp} Request received")
@app.after_request
def after_request(response):
timestamp = strftime('[%Y-%m-%d %T %z]')
logger.error('%s - - %s "%s %s" %s', request.remote_addr, timestamp,
request.method, request.full_path, response.status)
return response
Note: the code works with hypercorn + flask with a smallest payload but not with 100MB. Note: the output of the flask logger is empty. Which means that the request doesn't even reach flask (just hypercorn reject it somehow).
I have tried several combinations of configuration variables: h11_max_incomplete_size
, h2_max_concurrent_streams
, h2_max_header_list_size
, h2_max_inbound_frame_size
, max_app_queue_size
, backlog
, websocket_max_message_size
without any success.
This code works with flask alone or gunicorn+flask.
Any thoughts? Thank your for your help :+1:
Have you tried increasing the wsgi_max_body_size
config variable?
Hello, thank you for your answer. It works. :+1: I didn't find this parameter in the documentation: https://pgjones.gitlab.io/hypercorn/how_to_guides/configuring.html May be there is a more exhaustive documentation you can point me out?