From 5cc40ee3ba51b6b9592642b2e1dd66a0505ecc46 Mon Sep 17 00:00:00 2001 From: Oliver Urs Lenz Date: Wed, 8 Aug 2018 16:37:39 +0200 Subject: [PATCH] correct suffix order in ComplexHTTPRequestHandler --- pelican/server.py | 49 +++++++++++++----------------- pelican/tests/test_server.py | 58 ++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 pelican/tests/test_server.py diff --git a/pelican/server.py b/pelican/server.py index 09eeb493..0ba7b996 100644 --- a/pelican/server.py +++ b/pelican/server.py @@ -42,8 +42,7 @@ def parse_arguments(): class ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler): - SUFFIXES = ['', '.html', '/index.html'] - RSTRIP_PATTERNS = ['', '/'] + SUFFIXES = ['.html', '/index.html', '/', ''] def translate_path(self, path): # abandon query parameters @@ -67,34 +66,28 @@ class ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler): def do_GET(self): # cut off a query string - if '?' in self.path: - self.path, _ = self.path.split('?', 1) + original_path = self.path.split('?', 1)[0] + # try to find file + self.path = self.get_path_that_exists(original_path) - found = False - # Try to detect file by applying various suffixes and stripping - # patterns. - for rstrip_pattern in self.RSTRIP_PATTERNS: - if found: - break - for suffix in self.SUFFIXES: - if not hasattr(self, 'original_path'): - self.original_path = self.path - - self.path = self.original_path.rstrip(rstrip_pattern) + suffix - path = self.translate_path(self.path) - - if os.path.exists(path): - srvmod.SimpleHTTPRequestHandler.do_GET(self) - logging.info("Found `%s`.", self.path) - found = True - break - - logging.info("Tried to find `%s`, but it doesn't exist.", path) - - if not found: - # Fallback if there were no matches + if not self.path: logging.warning("Unable to find `%s` or variations.", - self.original_path) + original_path) + return + + logging.info("Found `%s`.", self.path) + srvmod.SimpleHTTPRequestHandler.do_GET(self) + + def get_path_that_exists(self, original_path): + # Try to strip trailing slash + original_path = original_path.rstrip('/') + # Try to detect file by applying various suffixes + for suffix in self.SUFFIXES: + path = original_path + suffix + if os.path.exists(self.translate_path(path)): + return path + logging.info("Tried to find `%s`, but it doesn't exist.", path) + return None def guess_type(self, path): """Guess at the mime type for the specified file. diff --git a/pelican/tests/test_server.py b/pelican/tests/test_server.py new file mode 100644 index 00000000..508b75ff --- /dev/null +++ b/pelican/tests/test_server.py @@ -0,0 +1,58 @@ +import os +from shutil import rmtree +from tempfile import mkdtemp + +from six import BytesIO + +from pelican.server import ComplexHTTPRequestHandler +from pelican.tests.support import unittest + + +class MockRequest(object): + def makefile(self, *args, **kwargs): + return BytesIO(b"") + + +class MockServer(object): + pass + + +class TestServer(unittest.TestCase): + + def setUp(self): + self.server = MockServer() + self.temp_output = mkdtemp(prefix='pelicantests.') + self.old_cwd = os.getcwd() + os.chdir(self.temp_output) + + def tearDown(self): + rmtree(self.temp_output) + os.chdir(self.old_cwd) + + def test_get_path_that_exists(self): + + handler = ComplexHTTPRequestHandler(MockRequest(), ('0.0.0.0', 8888), + self.server) + handler.base_path = self.temp_output + + os.mknod(os.path.join(self.temp_output, 'foo.html')) + os.mkdir(os.path.join(self.temp_output, 'foo')) + os.mknod(os.path.join(self.temp_output, 'foo', 'index.html')) + + os.mkdir(os.path.join(self.temp_output, 'bar')) + os.mknod(os.path.join(self.temp_output, 'bar', 'index.html')) + + os.mkdir(os.path.join(self.temp_output, 'baz')) + + for suffix in ['', '/']: + path = handler.get_path_that_exists('foo' + suffix) + self.assertEqual(path, 'foo.html') + + path = handler.get_path_that_exists('bar' + suffix) + self.assertEqual(path, 'bar/index.html') + + path = handler.get_path_that_exists('baz' + suffix) + self.assertEqual(path, 'baz/') + + path = handler.get_path_that_exists('quux' + suffix) + self.assertIsNone(path)