summaryrefslogtreecommitdiff
path: root/src/werkzeug/utils.py
diff options
context:
space:
mode:
authorDavid Lord <davidism@gmail.com>2020-07-13 22:35:10 -0700
committerDavid Lord <davidism@gmail.com>2020-07-13 22:35:10 -0700
commitffe81a50451736ecbd1b7c0247147f76e58f2c60 (patch)
treef477d36b03705fa6b3dbde83201d933bd3724220 /src/werkzeug/utils.py
parentf32a8dfe66dbeacd31c8b10d12c77efc1e0dd1d8 (diff)
downloadwerkzeug-ffe81a50451736ecbd1b7c0247147f76e58f2c60.tar.gz
add send_from_directory
Diffstat (limited to 'src/werkzeug/utils.py')
-rw-r--r--src/werkzeug/utils.py37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/werkzeug/utils.py b/src/werkzeug/utils.py
index 47742624..51b0439e 100644
--- a/src/werkzeug/utils.py
+++ b/src/werkzeug/utils.py
@@ -16,7 +16,9 @@ from ._internal import _DictAccessorProperty
from ._internal import _missing
from ._internal import _parse_signature
from .datastructures import Headers
+from .exceptions import NotFound
from .exceptions import RequestedRangeNotSatisfiable
+from .security import safe_join
from .urls import url_quote
from .wsgi import wrap_file
@@ -728,6 +730,41 @@ def send_file(
return rv
+def send_from_directory(directory, path, environ, **kwargs):
+ """Send a file from within a directory using :func:`send_file`.
+
+ This is a secure way to serve files from a folder, such as static
+ files or uploads. Uses :func:`~werkzeug.security.safe_join` to
+ ensure the path coming from the client is not maliciously crafted to
+ point outside the specified directory.
+
+ If the final path does not point to an existing regular file,
+ returns a 404 :exc:`~werkzeug.exceptions.NotFound` error.
+
+ :param directory: The directory that ``path`` must be located under.
+ :param path: The path to the file to send, relative to
+ ``directory``.
+ :param environ: The WSGI environ for the current request.
+ :param kwargs: Arguments to pass to :func:`send_file`.
+
+ .. versionadded:: 2.0.0
+ Adapted from Flask's implementation.
+ """
+ path = safe_join(os.fspath(directory), os.fspath(path))
+
+ if path is None:
+ raise NotFound()
+
+ try:
+ if not os.path.isfile(path):
+ raise NotFound()
+ except ValueError:
+ # path contains null byte on Python < 3.8
+ raise NotFound()
+
+ return send_file(path, environ, **kwargs)
+
+
def import_string(import_name, silent=False):
"""Imports an object based on a string. This is useful if you want to
use import paths as endpoints or something similar. An import path can