accumulate the whole response line for CGI scripts

This commit is contained in:
Omar Polo 2021-01-23 15:32:38 +00:00
parent 45b4aa6e57
commit 3309ef975c
4 changed files with 55 additions and 13 deletions

View File

@ -33,7 +33,7 @@ testdata: fill-file
./sha testdata/bigfile testdata/bigfile.sha
printf "# hello world\n" > testdata/index.gmi
./sha testdata/index.gmi testdata/index.gmi.sha
cp hello slow err testdata/
cp hello slow err invalid testdata/
mkdir testdata/dir
cp testdata/index.gmi testdata/dir/foo.gmi

3
regress/invalid Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
echo 'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii'

View File

@ -159,5 +159,9 @@ eq "$(head /err)" "" "Unexpected head for /err"
eq "$(get /err)" "" "Unexpected body for /err"
echo OK GET /err with cgi
eq "$(head /invalid | wc -c | xargs)" 2049 "Unexpected body for /invalid"
eq "$(get /invalid)" "" "Unexpected body for /invalid"
echo OK GET /invalid with cgi
check "should be running"
quit

View File

@ -448,6 +448,43 @@ cgi_poll_on_client(struct pollfd *fds, struct client *c)
c->fd = fd;
}
/* handle the read from the child process. Return like read(2) */
static ssize_t
read_from_cgi(struct client *c)
{
void *buf;
size_t len;
ssize_t r;
/* if we haven't read a whole response line, we want to
* continue reading. */
if (c->code == -1) {
buf = c->sbuf + c->len;
len = sizeof(c->sbuf) - c->len;
} else {
buf = c->sbuf;
len = sizeof(c->sbuf);
}
r = read(c->fd, buf, len);
if (r == 0 || r == -1)
return r;
c->len += r;
c->off = 0;
if (c->code != -1)
return r;
if (strchr(c->sbuf, '\n') || c->len == sizeof(c->sbuf)) {
c->code = 0;
log_request(c, c->sbuf, c->len);
}
return r;
}
void
handle_cgi(struct pollfd *fds, struct client *c)
{
@ -457,25 +494,23 @@ handle_cgi(struct pollfd *fds, struct client *c)
cgi_poll_on_client(fds, c);
while (1) {
if (c->len == 0) {
if ((r = read(c->fd, c->sbuf, sizeof(c->sbuf))) == 0)
if (c->code == -1 || c->len == 0) {
switch (r = read_from_cgi(c)) {
case 0:
goto end;
if (r == -1) {
case -1:
if (errno == EAGAIN || errno == EWOULDBLOCK) {
cgi_poll_on_child(fds, c);
return;
}
goto end;
goto end;
}
c->len = r;
c->off = 0;
}
/* XXX: if we haven't still read a whole
* reply line, we should go back to poll! */
if (c->code == -1) {
c->code = 0;
log_request(c, c->sbuf, sizeof(c->sbuf));
}
if (c->code == -1) {
cgi_poll_on_child(fds, c);
return;
}
while (c->len > 0) {