hypercorn icon indicating copy to clipboard operation
hypercorn copied to clipboard

Issue when sending large payload (HTTP CODE 400 or 104)

Open heavenboy8 opened this issue 2 years ago • 2 comments

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:

heavenboy8 avatar Nov 04 '22 14:11 heavenboy8

Have you tried increasing the wsgi_max_body_size config variable?

pgjones avatar Nov 05 '22 17:11 pgjones

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?

heavenboy8 avatar Nov 07 '22 08:11 heavenboy8