From 371b7dd01d8ac3804efd1d894c864bbfae8165e1 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Mon, 2 Sep 2019 20:58:22 -0400 Subject: [PATCH] Force directory paths to end with a trailing slash --- CHANGELOG.md | 5 +++++ jetforce.py | 19 +++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1958c3..19c6fc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Jetforce Changelog +### Unreleased + +- Force URLs to always end in trailing slashes when serving a directory. This + reduces duplicate selectors and makes resolving relative links more reliable. + ### v0.0.7 (2019-08-30) - Added support for a primitive version of CGI scripting. diff --git a/jetforce.py b/jetforce.py index 1119218..42fa77c 100755 --- a/jetforce.py +++ b/jetforce.py @@ -235,20 +235,23 @@ class StaticDirectoryApplication(JetforceApplication): if is_cgi and is_exe: return self.run_cgi_script(filesystem_path, request.environ) - else: - mimetype = self.guess_mimetype(filesystem_path.name) - generator = self.load_file(filesystem_path) - return Response(Status.SUCCESS, mimetype, generator) + mimetype = self.guess_mimetype(filesystem_path.name) + generator = self.load_file(filesystem_path) + return Response(Status.SUCCESS, mimetype, generator) elif filesystem_path.is_dir(): + if request.path and not request.path.endswith("/"): + url_parts = urllib.parse.urlparse(request.url) + url_parts = url_parts._replace(path=request.path + "/") + return Response(Status.REDIRECT_PERMANENT, url_parts.geturl()) + index_file = filesystem_path / self.index_file if index_file.exists(): generator = self.load_file(index_file) return Response(Status.SUCCESS, "text/gemini", generator) - else: - generator = self.list_directory(url_path, filesystem_path) - return Response(Status.SUCCESS, "text/gemini", generator) + generator = self.list_directory(url_path, filesystem_path) + return Response(Status.SUCCESS, "text/gemini", generator) else: return Response(Status.NOT_FOUND, "Not Found") @@ -310,7 +313,7 @@ class StaticDirectoryApplication(JetforceApplication): # Skip hidden and temporary files for security reasons continue elif file.is_dir(): - yield f"=>/{url_path / file.name}\t{file.name}/\r\n".encode() + yield f"=>/{url_path / file.name}/\t{file.name}/\r\n".encode() else: yield f"=>/{url_path / file.name}\t{file.name}\r\n".encode()