Large file download fails on slow network using HTTP/2 and AWS ALB

Given the following architecture:

client <-> AWS ALB <-> uwsgi <-> Django

The client fails to download a 12MB file when using HTTP/2 (the default), but works using HTTP/1.1. The file is streamed through Django for authentication purposes (it's fetched from a third party service).

Here is an example of failure (I'm using a Socks proxy to limit bandwidth):

$ curl -x socks5://localhost:1080 https://example.com/file.pdf --output "file.pdf"

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
 79 12.6M   79 10.0M    0     0  61254      0  0:03:36  0:02:51  0:00:45 64422
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)

However the same command with the flag --http1.1 works fine.

This fails when I limit downloads to 512kbps - it works at 1024Kbps. I've not looked for the sweet spot, it's not important.

Notes:

  • This also fails with a browser, it's not a curl issue
  • Using curl with -v doesn't give any additional information.
  • uwsgi does not output any errors. As far as it's concerned it did it's job. This is the output:
    [pid: 44|app: 0|req: 2603/9176] [ip] () {34 vars in 639 bytes} [Wed Oct 16 09:29:29 2024] GET /file.pdf => generated 13243923 bytes in 2425 msecs (HTTP/1.1 200) 8 headers in 314 bytes (103471 switches on core 0)
    
  • Similarly there are no issues listed in the ALB logs. It logs the request as a succesful request, but with a number of bytes lower than the expected amount.

I'd like to understanding why it's failing with HTTP/2 and a slow network. I suspect it's something to do with the ALB.

There are two things that could be done and people might suggest:

  • Put Nginx between the ALB and uwsgi
  • Don't stream the file through Django

Both of these are valid suggestions, however I'd like to understand what the problem is before deciding on a solution.

Вернуться на верх