summaryrefslogtreecommitdiffhomepage
path: root/test/test_static.py
diff options
context:
space:
mode:
authorAndrey Zelenkov <zelenkov@nginx.com>2019-09-19 17:11:37 +0300
committerAndrey Zelenkov <zelenkov@nginx.com>2019-09-19 17:11:37 +0300
commit2503226729bbb7b73ce3101818bfddec5efc155c (patch)
treead67c738d0efbf53ce895f19d244e11dbf11776d /test/test_static.py
parent08a8d1510d5f73d91112ead9e6ac075fb7d2bac0 (diff)
downloadunit-2503226729bbb7b73ce3101818bfddec5efc155c.tar.gz
unit-2503226729bbb7b73ce3101818bfddec5efc155c.tar.bz2
Tests: serving static files.
Diffstat (limited to 'test/test_static.py')
-rw-r--r--test/test_static.py376
1 files changed, 376 insertions, 0 deletions
diff --git a/test/test_static.py b/test/test_static.py
new file mode 100644
index 00000000..573669a3
--- /dev/null
+++ b/test/test_static.py
@@ -0,0 +1,376 @@
+import os
+import unittest
+from unit.applications.proto import TestApplicationProto
+
+
+class TestStatic(TestApplicationProto):
+ prerequisites = {}
+
+ def setUp(self):
+ super().setUp()
+
+ os.makedirs(self.testdir + '/assets/dir')
+ with open(self.testdir + '/assets/index.html', 'w') as index, \
+ open(self.testdir + '/assets/README', 'w') as readme, \
+ open(self.testdir + '/assets/log.log', 'w') as log, \
+ open(self.testdir + '/assets/dir/file', 'w') as file:
+ index.write('0123456789')
+ readme.write('readme')
+ log.write('[debug]')
+ file.write('blah')
+
+ self._load_conf(
+ {
+ "listeners": {"*:7080": {"pass": "routes"}},
+ "routes": [{"action": {"share": self.testdir + "/assets"}}],
+ "settings": {
+ "http": {
+ "static": {
+ "mime_types": {"text/plain": [".log", "README"]}
+ }
+ }
+ },
+ }
+ )
+
+ def test_static_index(self):
+ self.assertEqual(
+ self.get(url='/index.html')['body'], '0123456789', 'index'
+ )
+ self.assertEqual(self.get(url='/')['body'], '0123456789', 'index 2')
+ self.assertEqual(
+ self.get(url='/dir/')['status'], 404, 'index not found'
+ )
+
+ resp = self.get(url='/index.html/')
+ self.assertEqual(resp['status'], 404, 'index not found 2 status')
+ self.assertEqual(
+ resp['headers']['Content-Type'],
+ 'text/html',
+ 'index not found 2 Content-Type',
+ )
+
+ def test_static_large_file(self):
+ file_size = 32 * 1024 * 1024
+ with open(self.testdir + '/assets/large', 'wb') as f:
+ f.seek(file_size - 1)
+ f.write(b'\0')
+
+ self.assertEqual(
+ len(
+ self.get(url='/large', read_buffer_size=1024 * 1024)['body']
+ ),
+ file_size,
+ 'large file',
+ )
+
+ def test_static_etag(self):
+ etag = self.get(url='/')['headers']['ETag']
+ etag_2 = self.get(url='/README')['headers']['ETag']
+
+ self.assertNotEqual(etag, etag_2, 'different ETag')
+ self.assertEqual(
+ etag, self.get(url='/')['headers']['ETag'], 'same ETag'
+ )
+
+ with open(self.testdir + '/assets/index.html', 'w') as f:
+ f.write('blah')
+
+ self.assertNotEqual(
+ etag, self.get(url='/')['headers']['ETag'], 'new ETag'
+ )
+
+ def test_static_redirect(self):
+ resp = self.get(url='/dir')
+ self.assertEqual(resp['status'], 301, 'redirect status')
+ self.assertEqual(
+ resp['headers']['Location'], '/dir/', 'redirect Location'
+ )
+ self.assertNotIn(
+ 'Content-Type', resp['headers'], 'redirect Content-Type'
+ )
+
+ def test_static_space_in_name(self):
+ os.rename(
+ self.testdir + '/assets/dir/file',
+ self.testdir + '/assets/dir/fi le',
+ )
+ self.waitforfiles(self.testdir + '/assets/dir/fi le')
+ self.assertEqual(
+ self.get(url='/dir/fi le')['body'], 'blah', 'file name'
+ )
+
+ os.rename(self.testdir + '/assets/dir', self.testdir + '/assets/di r')
+ self.waitforfiles(self.testdir + '/assets/di r/fi le')
+ self.assertEqual(
+ self.get(url='/di r/fi le')['body'], 'blah', 'dir name'
+ )
+
+ os.rename(
+ self.testdir + '/assets/di r', self.testdir + '/assets/ di r '
+ )
+ self.waitforfiles(self.testdir + '/assets/ di r /fi le')
+ self.assertEqual(
+ self.get(url='/ di r /fi le')['body'], 'blah', 'dir name enclosing'
+ )
+
+ self.assertEqual(
+ self.get(url='/%20di%20r%20/fi le')['body'], 'blah', 'dir encoded'
+ )
+ self.assertEqual(
+ self.get(url='/ di r %2Ffi le')['body'], 'blah', 'slash encoded'
+ )
+ self.assertEqual(
+ self.get(url='/ di r /fi%20le')['body'], 'blah', 'file encoded'
+ )
+ self.assertEqual(
+ self.get(url='/%20di%20r%20%2Ffi%20le')['body'], 'blah', 'encoded'
+ )
+ self.assertEqual(
+ self.get(url='/%20%64%69%20%72%20%2F%66%69%20%6C%65')['body'],
+ 'blah',
+ 'encoded 2',
+ )
+
+ os.rename(
+ self.testdir + '/assets/ di r /fi le',
+ self.testdir + '/assets/ di r / fi le ',
+ )
+ self.waitforfiles(self.testdir + '/assets/ di r / fi le ')
+ self.assertEqual(
+ self.get(url='/%20di%20r%20/%20fi%20le%20')['body'],
+ 'blah',
+ 'file name enclosing',
+ )
+
+ try:
+ print('файл')
+ utf8 = True
+
+ except:
+ utf8 = False
+
+ if utf8:
+ os.rename(
+ self.testdir + '/assets/ di r / fi le ',
+ self.testdir + '/assets/ di r /фа йл',
+ )
+ self.waitforfiles(self.testdir + '/assets/ di r /фа йл')
+ self.assertEqual(
+ self.get(url='/ di r /фа йл')['body'], 'blah', 'file name 2'
+ )
+
+ os.rename(
+ self.testdir + '/assets/ di r ',
+ self.testdir + '/assets/ди ректория',
+ )
+ self.waitforfiles(self.testdir + '/assets/ди ректория/фа йл')
+ self.assertEqual(
+ self.get(url='/ди ректория/фа йл')['body'], 'blah', 'dir name 2'
+ )
+
+ def test_static_head(self):
+ resp = self.head(url='/')
+ self.assertEqual(resp['status'], 200, 'status')
+ self.assertEqual(resp['body'], '', 'empty body')
+
+ def test_static_two_clients(self):
+ _, sock = self.get(url='/', start=True, no_recv=True)
+ _, sock2 = self.get(url='/', start=True, no_recv=True)
+
+ self.assertEqual(sock.recv(1), b'H', 'client 1')
+ self.assertEqual(sock2.recv(1), b'H', 'client 2')
+ self.assertEqual(sock.recv(1), b'T', 'client 1 again')
+ self.assertEqual(sock2.recv(1), b'T', 'client 2 again')
+
+ sock.close()
+ sock2.close()
+
+ def test_static_mime_types(self):
+ self.assertIn(
+ 'success',
+ self.conf(
+ {
+ "text/x-code/x-blah/x-blah": "readme",
+ "text/plain": [".html", ".log", "file"],
+ },
+ 'settings/http/static/mime_types',
+ ),
+ 'configure mime_types',
+ )
+
+ self.assertEqual(
+ self.get(url='/README')['headers']['Content-Type'],
+ 'text/x-code/x-blah/x-blah',
+ 'mime_types string case insensitive',
+ )
+ self.assertEqual(
+ self.get(url='/index.html')['headers']['Content-Type'],
+ 'text/plain',
+ 'mime_types html',
+ )
+ self.assertEqual(
+ self.get(url='/')['headers']['Content-Type'],
+ 'text/plain',
+ 'mime_types index default',
+ )
+ self.assertEqual(
+ self.get(url='/dir/file')['headers']['Content-Type'],
+ 'text/plain',
+ 'mime_types file in dir',
+ )
+
+ def test_static_mime_types_partial_match(self):
+ self.assertIn(
+ 'success',
+ self.conf(
+ {
+ "text/x-blah": ["ile", "fil", "f", "e", ".file"],
+ },
+ 'settings/http/static/mime_types',
+ ),
+ 'configure mime_types',
+ )
+ self.assertNotIn(
+ 'Content-Type', self.get(url='/dir/file'), 'partial match'
+ )
+
+ def test_static_mime_types_reconfigure(self):
+ self.assertIn(
+ 'success',
+ self.conf(
+ {
+ "text/x-code": "readme",
+ "text/plain": [".html", ".log", "file"],
+ },
+ 'settings/http/static/mime_types',
+ ),
+ 'configure mime_types',
+ )
+
+ self.assertEqual(
+ self.conf_get('settings/http/static/mime_types'),
+ {'text/x-code': 'readme', 'text/plain': ['.html', '.log', 'file']},
+ 'mime_types get',
+ )
+ self.assertEqual(
+ self.conf_get('settings/http/static/mime_types/text%2Fx-code'),
+ 'readme',
+ 'mime_types get string',
+ )
+ self.assertEqual(
+ self.conf_get('settings/http/static/mime_types/text%2Fplain'),
+ ['.html', '.log', 'file'],
+ 'mime_types get array',
+ )
+ self.assertEqual(
+ self.conf_get('settings/http/static/mime_types/text%2Fplain/1'),
+ '.log',
+ 'mime_types get array element',
+ )
+
+ self.assertIn(
+ 'success',
+ self.conf_delete('settings/http/static/mime_types/text%2Fplain/2'),
+ 'mime_types remove array element',
+ )
+ self.assertNotIn(
+ 'Content-Type',
+ self.get(url='/dir/file')['headers'],
+ 'mime_types removed',
+ )
+
+ self.assertIn(
+ 'success',
+ self.conf_post(
+ '"file"', 'settings/http/static/mime_types/text%2Fplain'
+ ),
+ 'mime_types add array element',
+ )
+ self.assertEqual(
+ self.get(url='/dir/file')['headers']['Content-Type'],
+ 'text/plain',
+ 'mime_types reverted',
+ )
+
+ self.assertIn(
+ 'success',
+ self.conf(
+ '"file"', 'settings/http/static/mime_types/text%2Fplain'
+ ),
+ 'configure mime_types update',
+ )
+ self.assertEqual(
+ self.get(url='/dir/file')['headers']['Content-Type'],
+ 'text/plain',
+ 'mime_types updated',
+ )
+ self.assertNotIn(
+ 'Content-Type',
+ self.get(url='/log.log')['headers'],
+ 'mime_types updated 2',
+ )
+
+ self.assertIn(
+ 'success',
+ self.conf(
+ '".log"', 'settings/http/static/mime_types/text%2Fblahblahblah'
+ ),
+ 'configure mime_types create',
+ )
+ self.assertEqual(
+ self.get(url='/log.log')['headers']['Content-Type'],
+ 'text/blahblahblah',
+ 'mime_types create',
+ )
+
+ def test_static_mime_types_correct(self):
+ self.assertIn(
+ 'error',
+ self.conf(
+ {"text/x-code": "readme", "text/plain": "readme"},
+ 'settings/http/static/mime_types',
+ ),
+ 'mime_types same extensions',
+ )
+ self.assertIn(
+ 'error',
+ self.conf(
+ {"text/x-code": [".h", ".c"], "text/plain": ".c"},
+ 'settings/http/static/mime_types',
+ ),
+ 'mime_types same extensions array',
+ )
+ self.assertIn(
+ 'error',
+ self.conf(
+ {
+ "text/x-code": [".h", ".c", "readme"],
+ "text/plain": "README",
+ },
+ 'settings/http/static/mime_types',
+ ),
+ 'mime_types same extensions case insensitive',
+ )
+
+ @unittest.skip('not yet')
+ def test_static_mime_types_invalid(self):
+ self.assertIn(
+ 'error',
+ self.http(
+ b"""PUT /config/settings/http/static/mime_types/%0%00% HTTP/1.1\r
+Host: localhost\r
+Connection: close\r
+Content-Length: 6\r
+\r
+\"blah\"""",
+ raw_resp=True,
+ raw=True,
+ sock_type='unix',
+ addr=self.testdir + '/control.unit.sock',
+ ),
+ 'mime_types invalid',
+ )
+
+if __name__ == '__main__':
+ TestStatic.main()