diff --git a/tornado_xstatic.py b/tornado_xstatic.py index f42f359..d316b5a 100644 --- a/tornado_xstatic.py +++ b/tornado_xstatic.py @@ -6,6 +6,7 @@ class XStaticFileHandler(tornado.web.StaticFileHandler): _cached_xstatic_data_dirs = {} + default_filename = None def initialize(self, allowed_modules=None, **kwargs): if allowed_modules: @@ -13,25 +14,12 @@ def initialize(self, allowed_modules=None, **kwargs): else: self.allowed_modules = None - assert 'root' not in kwargs - # NOTE: Not wild on passing path=/ , because StaticFileHandler's own - # validation will let this serve any file. If this subclass is working - # correctly, that shouldn't be an issue, but... - super(XStaticFileHandler, self).initialize(path="/") - - def parse_url_path(self, url_path): - if '/' not in url_path: - raise tornado.web.HTTPError(403, "XStatic module, not a file") - if self.allowed_modules is not None: - module_name = url_path.split('/', 1)[0] - if module_name not in self.allowed_modules: - raise tornado.web.HTTPError( - 403, 'Access to XStatic module %s denied', module_name) - - return super(XStaticFileHandler, self).parse_url_path(url_path) + # Not calling parent initialize() here because there's no root to set. + # If SFH ever gains further attributes set in initialize(), we'll need + # to copy them here. @classmethod - def _get_xstatic_data_dir(cls, mod_name): + def get_xstatic_data_dir(cls, mod_name): try: return cls._cached_xstatic_data_dirs[mod_name] except KeyError: @@ -43,23 +31,29 @@ def _get_xstatic_data_dir(cls, mod_name): cls._cached_xstatic_data_dirs[mod_name] = data_dir return data_dir - @classmethod - def get_absolute_path(cls, root, path): - mod_name, path = path.split(os.path.sep, 1) - root = cls._get_xstatic_data_dir(mod_name) - abs_path = os.path.join(root, path) - if not abs_path.startswith(root): + def get(self, path, include_body=True): + if '/' not in path: + raise tornado.web.HTTPError(403, "XStatic module, not a file") + + mod, path = path.split('/') + if (self.allowed_modules is not None) and (mod not in self.allowed_modules): raise tornado.web.HTTPError( - 403, "Request for file outside XStatic package %s: %s", mod_name, path) + 403, 'Access to XStatic module %s denied', mod) - return abs_path + # This stateful setting of root seems awkward, but SFH is already stateful + # (self.path, self.absolute_path, self.modified), and from examining + # the code of SFH, this should work. + self.root = self.get_xstatic_data_dir(mod) + return super(XStaticFileHandler, self).get(path, include_body=include_body) def url_maker(prefix, include_version=True): def make_url(package, path): if include_version: - fs_style_path = package + os.path.sep + path.replace("/", os.path.sep) - version_bit = "?v=" + XStaticFileHandler.get_version({'static_path': ''}, fs_style_path) + fs_style_path = path.replace("/", os.path.sep) + pkg_dir = XStaticFileHandler.get_xstatic_data_dir(package) + version_bit = "?v=" + XStaticFileHandler.get_version( + {'static_path': pkg_dir}, fs_style_path) else: version_bit = "" return prefix + package + "/" + path + version_bit