From: Birk Nilson Date: Mon, 26 Mar 2012 10:02:13 +0000 (+0200) Subject: Cache the computed absolute path to the requested resource in X-Git-Tag: v3.1.0~67^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=38cccf8e53b41370f19a1914646e6949ba1fd907;p=thirdparty%2Ftornado.git Cache the computed absolute path to the requested resource in StaticFileHandler. The cache is cleared on_finish of each request in order to ensure recomputation on each request. --- diff --git a/tornado/web.py b/tornado/web.py index 2e4905805..20c382d5a 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -1489,11 +1489,10 @@ class StaticFileHandler(RequestHandler): def get(self, path, include_body=True): path = self.parse_url_path(path) - abspath = self.get_absolute_path(path) - if not self.set_headers(abspath, path): + if not self.set_headers(path): return - body = self.get_content(abspath) + body = self.get_content(path) if not body: return @@ -1506,6 +1505,13 @@ class StaticFileHandler(RequestHandler): assert self.request.method == "HEAD" self.set_header("Content-Length", len(body)) + def on_finish(self): + # Cleanup the cached computation of the absolute path associated with + # the requested resource. This is crucial in order to ensure accurate + # responses in upcoming requests which would otherwise utilize the same + # absolute path as the initial one - which would be chaotic. + self._abspath = None + def get_absolute_path(self, path): """Retrieve the absolute path on the filesystem where the resource corresponding to the given URL ``path`` can be found. @@ -1513,6 +1519,13 @@ class StaticFileHandler(RequestHandler): This method also handles the validation of the given path and ensures resources outside of the static directory cannot be accessed. """ + # In case the ``_abspath`` attribute exists and contains a value + # other than None the abspath has already been computed and verified. + # It can be returned instantly in order to avoid recomputation. + abspath = getattr(self, '_abspath', None) + if abspath is not None: + return abspath + abspath = os.path.abspath(os.path.join(self.root, path)) # os.path.abspath strips a trailing / # it needs to be temporarily added back for requests to root/ @@ -1530,13 +1543,16 @@ class StaticFileHandler(RequestHandler): raise HTTPError(404) if not os.path.isfile(abspath): raise HTTPError(403, "%s is not a file", path) + + self._abspath = abspath return abspath - def set_headers(self, abspath, path): + def set_headers(self, path): """Set the response headers in order to ensure that client browsers will cache the requested resource and not proceed to retrieve its content in the case of a 304 response. """ + abspath = self.get_absolute_path(path) stat_result = os.stat(abspath) modified = datetime.datetime.fromtimestamp(stat_result[stat.ST_MTIME]) @@ -1569,10 +1585,11 @@ class StaticFileHandler(RequestHandler): return True - def get_content(self, abspath): + def get_content(self, path): """Retrieve the content of the requested resource which is located - at the given ``abspath``. + at the given absolute ``path``. """ + abspath = self.get_absolute_path(path) with open(abspath, "rb") as file: return file.read() return None