Commit Diff


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) {