aboutsummaryrefslogtreecommitdiffstats
path: root/src/libtipidee/tipidee_fcgi_read.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2026-07-04 04:03:12 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2026-07-04 04:03:12 +0000
commit24daa5813f277023f7b8453338870369bf00a3ca (patch)
treefc19981595bd9be15daef821c0b5259c4f4907cb /src/libtipidee/tipidee_fcgi_read.c
parent45808dbc6dc1b90fa512add692252bc15760a214 (diff)
downloadtipidee-24daa5813f277023f7b8453338870369bf00a3ca.tar.gz
Implement FastCGI, initial version
Diffstat (limited to 'src/libtipidee/tipidee_fcgi_read.c')
-rw-r--r--src/libtipidee/tipidee_fcgi_read.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/libtipidee/tipidee_fcgi_read.c b/src/libtipidee/tipidee_fcgi_read.c
new file mode 100644
index 0000000..9b6dcb0
--- /dev/null
+++ b/src/libtipidee/tipidee_fcgi_read.c
@@ -0,0 +1,59 @@
+/* ISC license. */
+
+#include <stdint.h>
+#include <errno.h>
+
+#include <skalibs/uint16.h>
+#include <skalibs/uint32.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/unix-timed.h>
+
+#include <tipidee/fcgi.h>
+
+#include <skalibs/posixishard.h>
+
+int tipidee_fcgi_read (tipidee_fcgi *fc, uint32_t *status, stralloc *sa, tain *stamp)
+{
+ int stream ;
+ uint16_t u ;
+ char hdr[8] ;
+ if (buffer_timed_get(&fc->b, hdr, 8, &fc->deadline, stamp) < 8) return -1 ;
+ if (hdr[0] != 1) return (errno = EPROTO, -1) ;
+ uint16_unpack_big(hdr + 2, &u) ;
+ if (u != fc->id) return (errno = EPROTO, -1) ;
+ uint16_unpack_big(hdr + 4, &u) ;
+ switch (hdr[1])
+ {
+ case FCGI_STDOUT : stream = 1 ;
+ case FCGI_STDERR : stream = 2 ;
+ case FCGI_END_REQUEST : stream = 0 ;
+ default : return (errno = EPROTO, -1) ;
+ }
+ if (stream)
+ {
+ if (!stralloc_readyplus(sa, u)) return -1 ;
+ if (buffer_timed_get(&fc->b, sa->s + sa->len, u, &fc->deadline, stamp) < u) return -1 ;
+ sa->len += u ;
+ }
+ else
+ {
+ char endreq[8] ;
+ if (u != 8) return (errno = EPROTO, -1) ;
+ if (buffer_timed_get(&fc->b, endreq, 8, &fc->deadline, stamp) < 8) return -1 ;
+ switch (endreq[4])
+ {
+ case FCGI_REQUEST_COMPLETE : break ;
+ case FCGI_CANT_MPX_CONN : return (errno = ECONNREFUSED, -1) ;
+ case FCGI_OVERLOADED : return (errno = ENFILE, -1) ;
+ case FCGI_UNKNOWN_ROLE : return (errno = EAFNOSUPPORT, -1) ;
+ default : return (errno = EPROTO, 1) ;
+ }
+ uint32_unpack_big(endreq, status) ;
+ }
+ if (hdr[6])
+ {
+ char tmp[(uint8_t)hdr[6]] ;
+ if (buffer_timed_get(&fc->b, tmp, (uint8_t)hdr[6], &fc->deadline, stamp)) return -1 ;
+ }
+ return stream ;
+}