Is there an existing issue for this?
Describe the bug
The bug is that Sanic closes the connection before the final transfer of all data (see example below)
From my point of view this is a very critical bug. For a reason unknown to me, it repeats only when starting the Sanic server inside the docker container (i.e., perhaps it is somehow related to the networkmode or delays during the work of the docker).
After analyzing the commits, we managed to understand that the bug was introduced in 1310684 and not repeated on d1fc867
Code snippet
So we have really simple server returning some json demo.py:
from sanic import Sanic
from sanic.response import json
app = Sanic("Demo")
@app.route("/")
async def handle(request):
return json({'some_val': 'A'*743000})
if __name__ == "__main__":
app.run(host="0.0.0.0")
Running in docker container:
FROM python:3.11
COPY demo.py demo.py
RUN pip install sanic==23.12.1
ENTRYPOINT python3 demo.py
$ docker build -t demo .
$ docker run -p 127.0.0.1:8000:8000 --rm -it demo
and the client.py:
import socket
import sys
def getsock(ip, port, req):
s = socket.socket(2, 1, 6)
s.connect((ip, port))
s.send(req)
return s
REQ = (
b'GET / HTTP/1.1\r\n'
b'User-Agent: Mozilla/5.0\r\n'
b'Connection: close\r\n'
b'\r\n'
)
s = getsock('127.0.0.1', 8000, REQ)
headers = s.recv(94).decode()
print(f'Headers: {headers!r}')
total = 0
by_len = int(sys.argv[1])
while (data := s.recv(by_len)):
total += len(data)
print(f'Total length: {total}')
s.close()
I was not able to reproduce by curl, may be it's read too fast... But in real case it's repeats with Nginx proxy and Sanic as upstream.
so now if you will run hundred times you will get something like this:
$ for i in {1..100}; do python3 client.py 4096; done
...
Headers: 'HTTP/1.1 200 OK\r\ncontent-length: 743015\r\nconnection: close\r\ncontent-type: application/json\r\n\r\n'
Total length: 586346
Headers: 'HTTP/1.1 200 OK\r\ncontent-length: 743015\r\nconnection: close\r\ncontent-type: application/json\r\n\r\n'
Total length: 586346
Headers: 'HTTP/1.1 200 OK\r\ncontent-length: 743015\r\nconnection: close\r\ncontent-type: application/json\r\n\r\n'
Total length: 652954
Headers: 'HTTP/1.1 200 OK\r\ncontent-length: 743015\r\nconnection: close\r\ncontent-type: application/json\r\n\r\n'
Total length: 586346
Headers: 'HTTP/1.1 200 OK\r\ncontent-length: 743015\r\nconnection: close\r\ncontent-type: application/json\r\n\r\n'
Total length: 650058
Headers: 'HTTP/1.1 200 OK\r\ncontent-length: 743015\r\nconnection: close\r\ncontent-type: application/json\r\n\r\n'
Total length: 586346
Headers: 'HTTP/1.1 200 OK\r\ncontent-length: 743015\r\nconnection: close\r\ncontent-type: application/json\r\n\r\n'
Total length: 652954
Headers: 'HTTP/1.1 200 OK\r\ncontent-length: 743015\r\nconnection: close\r\ncontent-type: application/json\r\n\r\n'
Total length: 586346
...
So length should be 743015 but sanic returns only 586346-652954.
client.py must be runner outside the docker container, e.g on host. If you will run inside the docker it will not reproduce.
Expected Behavior
Return all the data from response.
How do you run Sanic?
Sanic CLI
Operating System
Linux
Sanic Version
v23.12.1
Additional context
No response
Is there an existing issue for this?
Describe the bug
The bug is that Sanic closes the connection before the final transfer of all data (see example below)
From my point of view this is a very critical bug. For a reason unknown to me, it repeats only when starting the Sanic server inside the docker container (i.e., perhaps it is somehow related to the networkmode or delays during the work of the docker).
After analyzing the commits, we managed to understand that the bug was introduced in 1310684 and not repeated on d1fc867
Code snippet
So we have really simple server returning some json demo.py:
Running in docker container:
$ docker build -t demo . $ docker run -p 127.0.0.1:8000:8000 --rm -it demoand the client.py:
I was not able to reproduce by curl, may be it's read too fast... But in real case it's repeats with Nginx proxy and Sanic as upstream.
so now if you will run hundred times you will get something like this:
So length should be 743015 but sanic returns only 586346-652954.
client.py must be runner outside the docker container, e.g on host. If you will run inside the docker it will not reproduce.
Expected Behavior
Return all the data from response.
How do you run Sanic?
Sanic CLI
Operating System
Linux
Sanic Version
v23.12.1
Additional context
No response