diff --git a/eris.c b/eris.c index 28ffc95..7567fa3 100644 --- a/eris.c +++ b/eris.c @@ -44,7 +44,7 @@ * the following is the time in seconds that fnord should wait for a valid * HTTP request */ -#define READTIMEOUT 20 +#define READTIMEOUT 2 /* * the following is the time in seconds that fnord should wait before @@ -217,7 +217,7 @@ elen(register const char *const *e) } static ssize_t -read_header(int fd, char *buf, size_t buflen) +read_header(int fd, char *buf, size_t buflen, size_t *headerlen) { size_t len = 0; int found = 0; @@ -235,15 +235,24 @@ read_header(int fd, char *buf, size_t buflen) } len += tmp; - for (; p < len; p += 1) { - if (buf[p] == '\n') { - if (++found == 2) { + for (; (found < 2) && (p < len); p += 1) { + switch (buf[p]) { + case '\n': + found += 1; + break; + case '\r': + break; + default: + found = 0; break; - } } } } + if (headerlen) { + *headerlen = p; + } + return len; } @@ -481,10 +490,11 @@ start_cgi(int nph, const char *pathinfo, const char *const *envp) if (startup) { /* XXX: could block :< */ - len = read_header(fd[0], ibuf, sizeof ibuf); + len = read_header(fd[0], ibuf, sizeof ibuf, NULL); } else { len = read(fd[0], ibuf, sizeof ibuf); } + DUMP_d(len); if (0 == len) { break; @@ -1457,8 +1467,8 @@ main(int argc, char *argv[], const char *const *envp) int dirlist = 0; int redirect = 0; int portappend = 0; - int len; - int in; + size_t len; + ssize_t in; { int opt; @@ -1491,48 +1501,9 @@ main(int argc, char *argv[], const char *const *envp) handlenext: encoding = 0; - // alarm(20); + alarm(READTIMEOUT); - { - int found = 0; - time_t fini, - now; - struct pollfd duh; - - fini = time(&now) + READTIMEOUT; - duh.fd = 0; - duh.events = POLLIN; - for (in = len = 0; found < 2;) { - int tmp; - switch (poll(&duh, 1, READTIMEOUT * 1000)) { - case 0: - if (time(&now) < fini) - continue; /* fall through */ - case -1: /* timeout or error */ - // badrequest(408,"Request Time-out","No request - // appeared - // within a reasonable time period."); - return 1; - } - tmp = read(0, buf + len, MAXHEADERLEN - len - 5); - if (tmp < 0) - return 1; - if (tmp == 0) - return 1; - in += tmp; - now = time(0); - for (; (found < 2) && (len < in); ++len) { - if (buf[len] == '\r') - continue; - if (buf[len] == '\n') - ++found; - else - found = 0; - if (found > 1) - break; - } - } - } + in = read_header(0, buf, sizeof buf, &len); if (len < 10) badrequest(400, "Bad Request", "
\n\n') - self.assertEqual(se, b'10.1.2.3 200 32 empty (null) (null) /\n') + self.assertLinesEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2\r\nConnection: close\r\nContent-Type: text/html; charset=utf-8\r\n\r\n
\n\n') + self.assertLinesEqual(se, b'10.1.2.3 200 32 empty (null) (null) /\n') def testNoTrailingSlash(self): so, se = self.get('/files', 'default') - self.assertEqual(so, b'HTTP/1.0 404 Not Found\r\nConnection: close\r\nContent-Length: 50\r\nContent-Type: text/html\r\n\r\n
\nParent directory\n[TXT] 1.txt\n\n') - self.assertEqual(se, b'10.1.2.3 200 110 default (null) (null) /files/\n') + self.assertLinesEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2\r\nConnection: close\r\nContent-Type: text/html; charset=utf-8\r\n\r\n
\nParent directory\n[TXT] 1.txt\n\n') + self.assertLinesEqual(se, b'10.1.2.3 200 110 default (null) (null) /files/\n') class CGITests(BasicTests): args = ['-c'] + maxDiff = None def testSet(self): so, se = self.get('/cgi/set.cgi', 'default') - self.assertEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2\r\nPragma: no-cache\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\nGATEWAY_INTERFACE:CGI/1.1\nSERVER_PROTOCOL:HTTP/1.0\nSERVER_SOFTWARE:eris/2\nSERVER_NAME:default\nSERVER_PORT:80\nREQUEST_METHOD:GET\nREQUEST_URI:/cgi/set.cgi\nSCRIPT_NAME:/cgi/set.cgi\nREMOTE_ADDR:10.1.2.3\nREMOTE_PORT:5858\n') - self.assertEqual(se, b'10.1.2.3 200 242 default (null) (null) /cgi/set.cgi\n') + self.assertLinesEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2\r\nPragma: no-cache\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\nGATEWAY_INTERFACE:CGI/1.1\nSERVER_PROTOCOL:HTTP/1.0\nSERVER_SOFTWARE:eris/2\nSERVER_NAME:default\nSERVER_PORT:80\nREQUEST_METHOD:GET\nREQUEST_URI:/cgi/set.cgi\nSCRIPT_NAME:/cgi/set.cgi\nREMOTE_ADDR:10.1.2.3\nREMOTE_PORT:5858\n') + self.assertLinesEqual(se, b'10.1.2.3 200 242 default (null) (null) /cgi/set.cgi\n') def testSetArgs(self): so, se = self.get('/cgi/set.cgi?a=1&b=2&c=3', 'default') - self.assertEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2\r\nPragma: no-cache\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\nGATEWAY_INTERFACE:CGI/1.1\nSERVER_PROTOCOL:HTTP/1.0\nSERVER_SOFTWARE:eris/2\nSERVER_NAME:default\nSERVER_PORT:80\nREQUEST_METHOD:GET\nREQUEST_URI:/cgi/set.cgi\nSCRIPT_NAME:/cgi/set.cgi\nREMOTE_ADDR:10.1.2.3\nREMOTE_PORT:5858\nQUERY_STRING:a=1&b=2&c=3\n') - self.assertEqual(se, b'10.1.2.3 200 267 default (null) (null) /cgi/set.cgi\n') + self.assertLinesEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2\r\nPragma: no-cache\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\nGATEWAY_INTERFACE:CGI/1.1\nSERVER_PROTOCOL:HTTP/1.0\nSERVER_SOFTWARE:eris/2\nSERVER_NAME:default\nSERVER_PORT:80\nREQUEST_METHOD:GET\nREQUEST_URI:/cgi/set.cgi\nSCRIPT_NAME:/cgi/set.cgi\nREMOTE_ADDR:10.1.2.3\nREMOTE_PORT:5858\nQUERY_STRING:a=1&b=2&c=3\n') + self.assertLinesEqual(se, b'10.1.2.3 200 267 default (null) (null) /cgi/set.cgi\n') def testPost(self): so, se = self.post('/cgi/set.cgi', 'default', 'a=1&b=2&c=3') - self.assertEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2\r\nPragma: no-cache\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\nGATEWAY_INTERFACE:CGI/1.1\nSERVER_PROTOCOL:HTTP/1.0\nSERVER_SOFTWARE:eris/2\nSERVER_NAME:default\nSERVER_PORT:80\nREQUEST_METHOD:POST\nREQUEST_URI:/cgi/set.cgi\nSCRIPT_NAME:/cgi/set.cgi\nREMOTE_ADDR:10.1.2.3\nREMOTE_PORT:5858\nCONTENT_TYPE:application/x-www-form-urlencoded\nCONTENT_LENGTH:11\nForm data: a=1&b=2&c=3') - self.assertEqual(se, b'10.1.2.3 200 330 default (null) (null) /cgi/set.cgi\n') + self.assertLinesEqual(se, b'10.1.2.3 200 330 default (null) (null) /cgi/set.cgi\n') + self.assertLinesEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2\r\nPragma: no-cache\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\nGATEWAY_INTERFACE:CGI/1.1\nSERVER_PROTOCOL:HTTP/1.0\nSERVER_SOFTWARE:eris/2\nSERVER_NAME:default\nSERVER_PORT:80\nREQUEST_METHOD:POST\nREQUEST_URI:/cgi/set.cgi\nSCRIPT_NAME:/cgi/set.cgi\nREMOTE_ADDR:10.1.2.3\nREMOTE_PORT:5858\nCONTENT_TYPE:application/x-www-form-urlencoded\nCONTENT_LENGTH:11\nForm data: a=1&b=2&c=3') + +# XXX: Test posting to static html with keepalive +# (it probably won't discard content-length octets) unittest.main()