6

reverse proxy FastCGI (fcgi) with uWSGI

 2 years ago
source link: https://blog.est.im/2021/stdout-017
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

reverse proxy FastCGI (fcgi) with uWSGI

Posted 2021-11-05 | 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

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.

Thanks for reading my shitpost. Questions?


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK