From fa113f8b47c909003aea0c0f35126f6598026506 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Wed, 20 Aug 2014 12:41:28 +0000 Subject: [PATCH] cgi: parse Status: header CGI applications can specify a HTTP status to output with the Status: header. For simplicity the CGI application must use this header on the first line. With this change cloning git repositories over HTTP with cgit works. in config.mk specify _GNU_SOURCE and _POSIX_C_SOURCE instead of _GNU_SOURCE, this is for getline(). --- config.mk | 2 +- quark.c | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/config.mk b/config.mk index 74099b6..a9314d0 100644 --- a/config.mk +++ b/config.mk @@ -12,7 +12,7 @@ INCS = -I. -I/usr/include LIBS = -L/usr/lib -lc # flags -CPPFLAGS = -DVERSION=\"${VERSION}\" -D_GNU_SOURCE +CPPFLAGS = -DVERSION=\"${VERSION}\" -D_POSIX_C_SOURCE=200809 -D_BSD_SOURCE CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} LDFLAGS = ${LIBS} #LDFLAGS = -s ${LIBS} diff --git a/quark.c b/quark.c index bf2bed6..6ae71b9 100644 --- a/quark.c +++ b/quark.c @@ -306,8 +306,9 @@ responsedir(void) { void responsecgi(void) { FILE *cgi; - size_t r; - char *q; + size_t r, linesiz = 0; + char *q, *line = NULL, *statusline = HttpOk; + ssize_t linelen; if (req.type == GET) setenv("REQUEST_METHOD", "GET", 1); @@ -338,15 +339,29 @@ responsecgi(void) { logerrmsg("error\tchdir to cgi directory %s failed: %s\n", cgi_dir, strerror(errno)); if ((cgi = popen(cgi_script, "r"))) { - if (putresentry(HEADER, HttpOk, tstamp(0))) - return; status = 200; + if ((linelen = getline(&line, &linesiz, cgi)) > 0) { + if (strncmp(line, "Status:", strlen("Status:")) == 0) { + statusline = line + strlen("Status:") + 1; + errno = 0; + status = strtol(statusline, NULL, 10); + if(errno) + status = 200; + if (putresentry(HEADER, statusline, tstamp(0))) + return; + writedata(line, linelen); + } else { + if (putresentry(HEADER, statusline, tstamp(0))) + return; + } + } while ((r = fread(resbuf, 1, MAXBUFLEN, cgi)) > 0) { if (writedata(resbuf, r)) { pclose(cgi); return; } } + free(line); pclose(cgi); } else { logerrmsg("error\t%s requests %s, but cannot run cgi script %s: %s\n",