commit 3309ef975cf570aeb5c1dbf568af323c19bbb3c0 from: Omar Polo date: Sat Jan 23 15:32:38 2021 UTC accumulate the whole response line for CGI scripts commit - 45b4aa6e57740fca189b4a2fd2ed9ed7ba3bf879 commit + 3309ef975cf570aeb5c1dbf568af323c19bbb3c0 blob - 863e5e4234144c39370f21019f74206d3f35e190 blob + f14b0fa6b92abb3152c6cf2e612b9d82636ad8f9 --- regress/Makefile +++ regress/Makefile @@ -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 blob - /dev/null blob + 97cca8c147dfa818430e2ab6d38b890f7e7b99dd (mode 755) --- /dev/null +++ regress/invalid @@ -0,0 +1,3 @@ +#!/bin/sh + +echo 'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii' blob - e9f193cc3a9f16d324e09900609c47dc57b74e3d blob + edfcf74c04aced1bf69cdf176f9a600807db00a7 --- regress/runtime +++ regress/runtime @@ -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 blob - 8337dcf388e3552cd08b25b422cd6fdfdbf4ec4e blob + 69d79c1b24fdac7dd0a4aa5e0a40c086b9579665 --- server.c +++ server.c @@ -447,7 +447,44 @@ cgi_poll_on_client(struct pollfd *fds, struct client * fds->fd = c->fd; 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) {