From 7b03cd62fb11ea708d0a15530a1bae83769d00c0 Mon Sep 17 00:00:00 2001 From: Ben Darnell Date: Sat, 25 May 2013 18:20:01 -0400 Subject: [PATCH] Avoid references to self.settings in StaticFileHandler instance methods. This fixes support for secondary StaticFileHandlers configured separately from the default static_path. Changed the interfaces of some new-to-3.1 methods to avoid passing in settings to class methods used in both class and instance contexts. Closes #796. --- tornado/test/web_test.py | 2 +- tornado/web.py | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index 676e38646..9ed42040e 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -1012,7 +1012,7 @@ class CustomStaticFileTest(WebTestCase): def get_absolute_path(cls, settings, path): return 'CustomStaticFileTest:' + path - def validate_absolute_path(self, absolute_path): + def validate_absolute_path(self, root, absolute_path): return absolute_path @classmethod diff --git a/tornado/web.py b/tornado/web.py index f670d8aa7..b8b22dd6c 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -1767,7 +1767,7 @@ class StaticFileHandler(RequestHandler): _lock = threading.Lock() # protects _static_hashes def initialize(self, path, default_filename=None): - self.root = os.path.abspath(path) + os.path.sep + self.root = path self.default_filename = default_filename @classmethod @@ -1782,8 +1782,9 @@ class StaticFileHandler(RequestHandler): # Set up our path instance variables. self.path = self.parse_url_path(path) del path # make sure we don't refer to path instead of self.path again - absolute_path = self.get_absolute_path(self.settings, self.path) - self.absolute_path = self.validate_absolute_path(absolute_path) + absolute_path = self.get_absolute_path(self.root, self.path) + self.absolute_path = self.validate_absolute_path( + self.root, absolute_path) if self.absolute_path is None: return @@ -1883,21 +1884,26 @@ class StaticFileHandler(RequestHandler): return False @classmethod - def get_absolute_path(cls, settings, path): - """Returns the absolute location of ``path``. + def get_absolute_path(cls, root, path): + """Returns the absolute location of ``path`` relative to ``root``. + + ``root`` is the path configured for this `StaticFileHandler` + (in most cases the ``static_path`` `Application` setting). This class method may be overridden in subclasses. By default it returns a filesystem path, but other strings may be used as long as they are unique and understood by the subclass's overridden `get_content`. """ - root = settings["static_path"] abspath = os.path.abspath(os.path.join(root, path)) return abspath - def validate_absolute_path(self, absolute_path): + def validate_absolute_path(self, root, absolute_path): """Validate and return the absolute path. + ``root`` is the configured path for the `StaticFileHandler`, + and ``path`` is the result of `get_absolute_path` + This is an instance method called during request processing, so it may raise `HTTPError` or use methods like `RequestHandler.redirect` (return None after redirecting to @@ -1910,7 +1916,6 @@ class StaticFileHandler(RequestHandler): In instance methods, this method's result is available as ``self.absolute_path``. """ - root = os.path.abspath(self.settings["static_path"]) # os.path.abspath strips a trailing / # it needs to be temporarily added back for requests to root/ if not (absolute_path + os.path.sep).startswith(root): @@ -2084,7 +2089,7 @@ class StaticFileHandler(RequestHandler): `get_content_version` is now preferred as it allows the base class to handle caching of the result. """ - abs_path = cls.get_absolute_path(settings, path) + abs_path = cls.get_absolute_path(settings['static_path'], path) return cls._get_cached_version(abs_path) @classmethod -- 2.47.2