diff --git a/tests.sh b/test.sh similarity index 71% rename from tests.sh rename to test.sh index 0caee20..ddca01e 100755 --- a/tests.sh +++ b/test.sh @@ -39,20 +39,24 @@ d () { } -if [ ! -d default ]; then - mkdir default - echo james > default/index.html - touch default/a - cat < default/a.cgi +mkdir -p default +echo james > default/index.html +touch default/a +cat <<'EOD' > default/a.cgi #! /bin/sh echo 'Content-type: text/plain' ls / > /dev/null # delay a little echo -echo james -EOD - chmod +x default/a.cgi - mkdir empty:80 +if [ -n "$CONTENT_LENGTH" ]; then + echo "t:$CONTENT_TYPE" + echo -n "v:" + dd bs=1 count=$CONTENT_LENGTH 2>/dev/null +else + echo ${QUERY_STRING:-james} fi +EOD +chmod +x default/a.cgi +mkdir -p default/empty echo "HTTPD: $HTTPD " echo "CGI: $HTTPD_CGI " @@ -66,6 +70,9 @@ printf 'GET / HTTP/1.0\r\n\r\n' | $HTTPD 2>/dev/null | d | grep -q 'HTTP/1.0 200 title "POST" printf 'POST / HTTP/1.0\r\nContent-Type: a\r\nContent-Length: 5\r\n\r\njames' | $HTTPD 2>/dev/null | d | grep -q 'HTTP/1.0 200 OK#%Server: [a-z]*/[0-9.]*#%Content-Type: text/html; charset=UTF-8#%Content-Length: 6#%Last-Modified: ..., .. ... 20.. ..:..:.. GMT#%#%james%' && pass || fail +title "Bare newline" +printf 'GET / HTTP/1.0\n\n' | $HTTPD 2>/dev/null | d | grep -q 'HTTP/1.0 200 OK#%Server: [a-z]*/[0-9.]*#%Content-Type: text/html; charset=UTF-8#%Content-Length: 6#%Last-Modified: ..., .. ... 20.. ..:..:.. GMT#%#%james%' && pass || fail + title "Logging /" (printf 'GET / HTTP/1.1\r\nHost: host\r\n\r\n' | PROTO=TCP TCPREMOTEPORT=1234 TCPREMOTEIP=10.0.0.2 $HTTPD >/dev/null) 2>&1 | grep -q '^10.0.0.2 200 6 host (null) (null) /$' && pass || fail @@ -74,6 +81,28 @@ title "Logging /index.html" (printf 'GET /index.html HTTP/1.1\r\nHost: host\r\n\r\n' | PROTO=TCP TCPREMOTEPORT=1234 TCPREMOTEIP=10.0.0.2 $HTTPD >/dev/null) 2>&1 | grep -q '^10.0.0.2 200 6 host (null) (null) /index.html$' && pass || fail + +H "Directory indexing" + +title "Basic index" +printf 'GET /empty/ HTTP/1.0\r\n\r\n' | $HTTPD_IDX 2>/dev/null | d | grep -Fq '

Directory Listing: /empty/

%
%Parent directory%
%' && pass || fail + +title "No trailing slash" +printf 'GET /empty HTTP/1.0\r\n\r\n' | $HTTPD_IDX 2>/dev/null | d | grep -Fq '404 Not Found' && pass || fail + + +H "CGI" + +title "Basic CGI" +printf 'GET /a.cgi HTTP/1.0\r\n\r\n' | $HTTPD_CGI 2>/dev/null | d | grep -q 'HTTP/1.0 200 OK#%Server: .*#%Pragma: no-cache#%Connection: close#%Content-type: text/plain#%#%james%' && pass || fail + +title "GET with arguments" +printf 'GET /a.cgi?foo HTTP/1.0\r\n\r\n' | $HTTPD_CGI 2>/dev/null | d | grep -q 'HTTP/1.0 200 OK#%Server: .*#%Pragma: no-cache#%Connection: close#%Content-type: text/plain#%#%foo%' && pass || fail + +title "POST" +printf 'POST /a.cgi HTTP/1.0\r\nContent-Type: moo\r\nContent-Length: 3\r\n\r\narf' | $HTTPD_CGI 2>/dev/null | d | grep -q 't:moo%v:arf$' && pass || fail + + H "fnord bugs" # 1. Should return directory listing of /; instead segfaults @@ -111,6 +140,7 @@ title "HTTP/1.1 default keepalive" printf 'GET / HTTP/1.1\r\nHost: a\r\n\r\n') | $HTTPD 2>/dev/null | grep -c '^HTTP/' | grep -q 2 && pass || fail BR + echo "$successes of $tests tests passed ($failures failed)." exit $failures diff --git a/tests/default/cgi/set.cgi b/tests/default/cgi/set.cgi deleted file mode 100755 index c8fe9da..0000000 --- a/tests/default/cgi/set.cgi +++ /dev/null @@ -1,23 +0,0 @@ -#! /bin/sh - -echo Content-Type: text/plain -echo -for k in GATEWAY_INTERFACE \ - SERVER_PROTOCOL SERVER_SOFTWARE SERVER_NAME SERVER_PORT \ - REQUEST_METHOD REQUEST_URI \ - SCRIPT_NAME \ - REMOTE_ADDR REMOTE_PORT REMOTE_IDENT \ - HTTP_USER_AGENT HTTP_COOKIE HTTP_REFERER HTTP_ACCEPT_ENCODING \ - AUTH_TYPE \ - CONTENT_TYPE CONTENT_LENGTH \ - QUERY_STRING \ - PATH_INFO PATH_TRANSLATED; do - v=$(eval echo \${$k}) - if [ -n "$v" ]; then - echo "$k:$v" - fi -done -if [ -n "$CONTENT_TYPE" ]; then - echo -n "Form data: " - dd bs=1 count=$CONTENT_LENGTH 2>/dev/null -fi diff --git a/tests/default/files/1.txt b/tests/default/files/1.txt deleted file mode 100644 index e69de29..0000000 diff --git a/tests/default/index.html b/tests/default/index.html deleted file mode 100644 index dc065e0..0000000 --- a/tests/default/index.html +++ /dev/null @@ -1 +0,0 @@ -james diff --git a/tests/empty/.empty b/tests/empty/.empty deleted file mode 100644 index e69de29..0000000 diff --git a/tests/test.py b/tests/test.py deleted file mode 100755 index 017577d..0000000 --- a/tests/test.py +++ /dev/null @@ -1,122 +0,0 @@ -#! /usr/bin/python3 - -import unittest -from subprocess import * -import os - -def eris(*args): - return Popen(('../eris',) + args, - stdin=PIPE, stdout=PIPE, stderr=PIPE, - env={'PROTO': 'TCP', - 'TCPREMOTEPORT': '5858', - 'TCPREMOTEIP': '10.1.2.3'}) - -class LinesTests(unittest.TestCase): - def assertLinesEqual(self, a, b): - self.assertSequenceEqual(a.split(b'\n'), b.split(b'\n')) - -class NewlineTests(LinesTests): - def testBareNL(self): - - p = eris() - so, se = p.communicate(b'GET / HTTP/1.0\n\n') - self.assertRegexpMatches(so, b'HTTP/1.0 200 OK\r\nServer: eris/2.0\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: 6\r\nLast-Modified: (Mon|Tue|Wed|Thu|Fri|Sat|Sun), .. (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) 2... ..:..:.. GMT\r\n\r\njames\n') - self.assertLinesEqual(se, b'10.1.2.3 200 6 127.0.0.1 (null) (null) /index.html\n') - - -class ArgTests(LinesTests): - def check_index(self, *args): - p = eris(*args) - so, se = p.communicate(b'GET / HTTP/1.0\r\n\r\n') - self.assertRegexpMatches(so, b'HTTP/1.0 200 OK\r\nServer: eris/2.0\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: 6\r\nLast-Modified: (Mon|Tue|Wed|Thu|Fri|Sat|Sun), .. (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) 2... ..:..:.. GMT\r\n\r\njames\n') - self.assertLinesEqual(se, b'10.1.2.3 200 6 127.0.0.1 (null) (null) /index.html\n') - - def testArgs(self): - "Make sure index.html is the same for all arguments" - - self.check_index() - self.check_index('-d') - self.check_index('-r') - self.check_index('-c') - - def testPortAppend(self): - p = eris('-p') - so, se = p.communicate(b'GET / HTTP/1.0\r\n\r\n') - self.assertRegexpMatches(so, b'HTTP/1.0 200 OK\r\nServer: eris/2.0\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: 6\r\nLast-Modified: (Mon|Tue|Wed|Thu|Fri|Sat|Sun), .. (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) 2... ..:..:.. GMT\r\n\r\njames\n') - self.assertLinesEqual(se, b'10.1.2.3 200 6 127.0.0.1:80 (null) (null) /index.html\n') - - def testBadArgs(self): - "Make sure bad arguments actually fail" - - self.assertRaises(AssertionError, self.check_index, '-Z') - - -class BasicTests(LinesTests): - args = [] - - def setUp(self): - self.p = eris(*self.args) - - def tearDown(self): - del self.p - - def get(self, path, host): - h = 'GET %s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host) - so, se = self.p.communicate(h.encode('utf-8')) - return (so, se) - - def post(self, path, host, formdata): - h = 'POST %s HTTP/1.0\r\nHost: %s\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n\r\n%s' % (path, host, len(formdata), formdata) - so, se = self.p.communicate(h.encode('utf-8')) - return (so, se) - - -class DirTests(BasicTests): - args = ['-d'] - - def testRootDir(self): - so, se = self.get('/', 'empty') - self.assertLinesEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2.0\r\nConnection: close\r\nContent-Type: text/html; charset=utf-8\r\n\r\n

Directory Listing: /

\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.assertLinesEqual(so, b'HTTP/1.0 404 Not Found\r\nConnection: close\r\nContent-Length: 67\r\nContent-Type: text/html\r\n\r\nNo such file or directory.No such file or directory.') - self.assertLinesEqual(se, b'10.1.2.3 404 0 default (null) (null) /files\n') - - def testFiles(self): - so, se = self.get('/files/', 'default') - - self.assertLinesEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2.0\r\nConnection: close\r\nContent-Type: text/html; charset=utf-8\r\n\r\n

Directory Listing: /files/

\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.assertLinesEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2.0\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.0\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 218 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.assertLinesEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2.0\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.0\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 243 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.assertLinesEqual(se, b'10.1.2.3 200 306 default (null) (null) /cgi/set.cgi\n') - self.assertLinesEqual(so, b'HTTP/1.0 200 OK\r\nServer: eris/2.0\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.0\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') - -class BufferingTests(BasicTests): - def testDoubleGet(self): - so, se = self.p.communicate(b'GET / HTTP/1.0\r\n\r\nGET / HTTP/1.0\r\n\r\n') - self.assertLinesEqual(so, b'') - -# XXX: Test posting to static html with keepalive -# (it probably won't discard content-length octets) - -unittest.main() -