I installed uWSGI in a Docker container running ubuntu:16.04
using the following commands:
apt-get update
apt-get install -y build-essential python-dev python-pip
pip install uwsgi
I then created a single static file:
cd /root
mkdir static
dd if=/dev/zero bs=1 count=1024 of=static/data
...and finally started uWSGI with the following command:
uwsgi \
--buffer-size 32768 \
--http-socket 0.0.0.0:80 \
--processes 4 \
--http-timeout 60 \
--http-keepalive \
--static-map2=/static=./
I was able to access the static file without any problems. However, despite passing the --http-keepalive
option, issuing multiple requests with cURL resulted in the following output:
# curl -v 'http://myserver/static/data' -o /dev/null 'http://myserver/static/data' -o /dev/null
* Trying 192.168.1.101...
...
> GET /static/data HTTP/1.1
> Host: 192.168.1.101:8100
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 1024
< Last-Modified: Sat, 03 Dec 2016 22:06:49 GMT
<
{ [1024 bytes data]
100 1024 100 1024 0 0 577k 0 --:--:-- --:--:-- --:--:-- 1000k
* Connection #0 to host 192.168.1.101 left intact
* Found bundle for host 192.168.1.101: 0x563fbc855630 [can pipeline]
* Connection 0 seems to be dead!
* Closing connection 0
...
Of particular interest is the line:
* Connection 0 seems to be dead!
This was confirmed with WireShark:
As you can see, there are two completely separate TCP connections. The first one is closed by uWSGI (packet #10 - the [FIN, ACK]
).
What am I doing wrong? Why doesn't uWSGI honor the --http-keepalive
flag instead of immediately closing the connection?
I was finally able to get keepalive working by switching from --http-socket
to simply --http
. According to uWSGI docs:
If your web server does not support the uwsgi protocol but is able to speak to upstream HTTP proxies, or if you are using a service like Webfaction or Heroku to host your application, you can use
http-socket
. If you plan to expose your app to the world with uWSGI only, use thehttp
option instead, as the router/proxy/load-balancer will then be your shield.
In my particular case, it was also necessary to load the http
plugin.