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
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.
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/
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])
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