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().
This commit is contained in:
Hiltjo Posthuma 2014-08-20 12:41:28 +00:00 committed by FRIGN
parent 8b6bdd39ff
commit fa113f8b47
2 changed files with 20 additions and 5 deletions

View file

@ -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}

23
quark.c
View file

@ -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",