FU: Add FastCGI support + bunch of fixes

I initially planned to only implement the bare minimum to support
FastCGI under nginx, but ended up implementing the full protocol
instead. This is more code than I had expected and the code is also less
trivial than I had hoped. Will need to do more testing, pretty sure
there's bugs left.

Also TODO: test under alternative process managers + document
FU_LISTEN_PROTO.

I've also removed the max_request_body setting, this is something that
really ought to be configured in the web server instead.
This commit is contained in:
Yorhel 2025-02-17 15:10:44 +01:00
parent 3e84a4f4d3
commit d9fba4e8d8
4 changed files with 784 additions and 79 deletions

42
FU.xs
View file

@ -25,6 +25,7 @@
#include "c/jsonfmt.c"
#include "c/jsonparse.c"
#include "c/fdpass.c"
#include "c/fcgi.c"
#include "c/libpq.h"
#include "c/pgtypes.c"
#include "c/pgconn.c"
@ -55,11 +56,16 @@ PROTOTYPES: DISABLE
TYPEMAP: <<EOT
TYPEMAP
fufcgi * FUFCGI
fupg_conn * FUPG_CONN
fupg_txn * FUPG_TXN
fupg_st * FUPG_ST
INPUT
FUFCGI
if (sv_derived_from($arg, \"FU::fcgi\")) $var = (fufcgi *)SvIVX(SvRV($arg));
else fu_confess(\"invalid FastCGI object\");
FUPG_CONN
if (sv_derived_from($arg, \"FU::Pg::conn\")) $var = (fupg_conn *)SvIVX(SvRV($arg));
else fu_confess(\"invalid connection object\");
@ -96,6 +102,42 @@ void fdpass_recv(int socket, UV len)
XSRETURN(fufdpass_recv(aTHX_ ax, socket, len));
MODULE = FU PACKAGE = FU::fcgi
void new(int fd, int maxproc)
CODE:
fufcgi *ctx = safemalloc(sizeof(*ctx));
ctx->fd = fd;
ctx->maxproc = maxproc;
ctx->reqid = ctx->keepconn = ctx->len = ctx->off = 0;
ST(0) = fu_selfobj(ctx, "FU::fcgi");
void read_req(fufcgi *ctx, SV *headers, SV *params)
CODE:
ST(0) = sv_2mortal(newSViv(fufcgi_read_req(aTHX_ ctx, headers, params)));
ctx->off = 8;
void keepalive(fufcgi *ctx)
CODE:
ST(0) = ctx->keepconn ? &PL_sv_yes : &PL_sv_no;
void print(fufcgi *ctx, SV *sv)
CODE:
STRLEN len;
const char *buf = SvPVbyte(sv, len);
fufcgi_print(ctx, buf, len);
void flush(fufcgi *ctx)
CODE:
fufcgi_flush(ctx);
ctx->off = ctx->len = ctx->reqid = 0;
void DESTROY(fufcgi *ctx)
CODE:
safefree(ctx);
MODULE = FU PACKAGE = FU::Pg
void _load_libpq()