reverse proxy FastCGI (fcgi) with uWSGI
Posted | stdout
People are still using FastCGI, and it's hard. I used uWSGI to convert FCGI traffic to regular http/1.0 so I can keep my existing http service running without apache mod_fcgi shit.
CGI environ variables
This is some ancient knowledge, better keep them noted
KEY | description |
---|---|
AUTH_TYPE | ignore this |
REMOTE_IDENT | The user making the request. |
REMOTE_USER | The authenticated name of the user making the query. |
CONTENT_LENGTH | byte length of body |
CONTENT_TYPE | MIME such as text/html, without the charset shit |
DOCUMENT_ROOT | NEW. The directory from which web documents are served. |
REQUEST_URI | NEW. confusing shit similar with PATH_INFO |
HTTP_* | HTTP headers |
PATH_INFO | like /a/b/c |
PATH_TRANSLATED | not really used |
QUERY_STRING | the part after ? in an URL |
REMOTE_ADDR | client IP |
REMOTE_HOST | client host name by lookup ip |
REQUEST_METHOD | GET/POST |
SCRIPT_NAME | The virtual path (e.g., /cgi-bin/program.pl) of the script being executed. |
SCRIPT_FILENAME | confusing shit similar with SCRIPT_NAME |
SERVER_NAME | The server's hostname or IP address. |
SERVER_PORT | The port number of the host on which the server is running. |
SERVER_PROTOCOL | The name and revision number of the server protocol. |
reverse proxy FastCGI with uWSGI
slap this into my_conf.ini
[uwsgi]
my_port = 9000 # can be set otherwise
route-run = addvar:SERVER_NAME=%h
route-run = addvar:SERVER_PORT=%(my_port)
route-if = empty:${REQUEST_METHOD} addvar:REQUEST_METHOD=GET
route-if = empty:${HTTP_HOST} addvar:HTTP_HOST=%h:%(my_port)
route-run = seturi:/fcgi-proxy${PATH_INFO}
route-run = http:127.0.0.1:9527
fastcgi-socket = 0.0.0.0:%(my_port)
http-socket = 0.0.0.0:8000 # for testing purpose.
Install uWSGI, install the binary from pypi wheels instead of compiling uwsgi.c shit
pip install pyuwsgi
Run it
uwsgi --ini my_conf.ini
Now you can run your regular http service behind 127.0.0.1:9527
, while serving fcgi on 127.0.0.1:9000
Requests like fcgi://127.0.0.1:9000/hello
will be fowwarded to http://127.0.0.1:9527/fcgi-proxy/hello
You may ask why adding a /fcgi-proxy
in path? Because there's a gotcha.
fuckedup FastCGI requests
Learned this from some php-fpm tutorial, first install the standard fcgi client tool because curl
doesn't speak fcgi.
apt-get install libfcgi0ldbl
yum --enablerepo=epel install fcgi
SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000
You can observe from uWSGI logs that cgi-fcgi
command sends flawed requests, the PATH_INFO
was unset.
After hours wasted, I came up with a clever hack to force uWSGI's internal router to force seturi
with a path prefix
ToDo
There are further problems that can be improved, for example, my http service is running uvicorn
, it can not guess the client ip:port infor from its stupid get_remote_addr
what's worse, the uWSGI addheader
directive are for responses, so I can't add request headers like x-forwared-for
.
Also the reverse proxy is HTTP/1.0 only. to make the Connection: Keep-alive
happen needs some further investigation.
Q&A
Thanks for reading my shitpost. Questions?
Comments