Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def __call__(self, environ, start_response):
path = environ["PATH_INFO"]
dav_res = None
if environ["wsgidav.provider"]:
dav_res = environ["wsgidav.provider"].get_resource_inst(path, environ)
if (
environ["REQUEST_METHOD"] in ("GET", "HEAD")
and dav_res
and dav_res.is_collection
):
if util.get_content_length(environ) != 0:
self._fail(
HTTP_MEDIATYPE_NOT_SUPPORTED,
"The server does not handle any body content.",
)
if environ["REQUEST_METHOD"] == "HEAD":
return util.send_status_response(
environ, start_response, HTTP_OK, is_head=True
)
# Support DAV mount (http://www.ietf.org/rfc/rfc4709.txt)
if self.dir_config.get("davmount") and "davmount" in environ.get(
"QUERY_STRING", ""
):
collectionUrl = util.make_complete_url(environ)
collectionUrl = collectionUrl.split("?", 1)[0]
def _debug_exception(e):
"""Log internal exceptions with stacktrace that otherwise would be hidden."""
if self._verbose >= 5:
_logger.exception("_debug_exception")
return
# --- Check source ----------------------------------------------------
if srcRes is None:
self._fail(HTTP_NOT_FOUND, srcPath)
if "HTTP_DESTINATION" not in environ:
self._fail(HTTP_BAD_REQUEST, "Missing required Destination header.")
if not environ.setdefault("HTTP_OVERWRITE", "T") in ("T", "F"):
# Overwrite defaults to 'T'
self._fail(HTTP_BAD_REQUEST, "Invalid Overwrite header.")
if util.get_content_length(environ) != 0:
# RFC 2518 defined support for .
# This was dropped with RFC 4918.
# Still clients may send it (e.g. DAVExplorer 0.9.1 File-Copy) sends
# *
body = environ["wsgi.input"].read(util.get_content_length(environ))
environ["wsgidav.all_input_read"] = 1
_logger.info("Ignored copy/move body: '{}'...".format(body[:50]))
if srcRes.is_collection:
# The COPY method on a collection without a Depth header MUST act as
# if a Depth header with value "infinity" was included.
# A client may submit a Depth header on a COPY on a collection with
# a value of "0" or "infinity".
environ.setdefault("HTTP_DEPTH", "infinity")
if not environ["HTTP_DEPTH"] in ("0", "infinity"):
self._fail(HTTP_BAD_REQUEST, "Invalid Depth header.")
# --- Check source ----------------------------------------------------
if srcRes is None:
self._fail(HTTP_NOT_FOUND, srcPath)
if "HTTP_DESTINATION" not in environ:
self._fail(HTTP_BAD_REQUEST, "Missing required Destination header.")
if not environ.setdefault("HTTP_OVERWRITE", "T") in ("T", "F"):
# Overwrite defaults to 'T'
self._fail(HTTP_BAD_REQUEST, "Invalid Overwrite header.")
if util.get_content_length(environ) != 0:
# RFC 2518 defined support for .
# This was dropped with RFC 4918.
# Still clients may send it (e.g. DAVExplorer 0.9.1 File-Copy) sends
# *
body = environ["wsgi.input"].read(util.get_content_length(environ))
environ["wsgidav.all_input_read"] = 1
_logger.info("Ignored copy/move body: '{}'...".format(body[:50]))
if srcRes.is_collection:
# The COPY method on a collection without a Depth header MUST act as
# if a Depth header with value "infinity" was included.
# A client may submit a Depth header on a COPY on a collection with
# a value of "0" or "infinity".
environ.setdefault("HTTP_DEPTH", "infinity")
if not environ["HTTP_DEPTH"] in ("0", "infinity"):
self._fail(HTTP_BAD_REQUEST, "Invalid Depth header.")
if is_move and environ["HTTP_DEPTH"] != "infinity":
self._fail(
HTTP_BAD_REQUEST,
"Depth header for MOVE collection must be 'infinity'.",
)
def do_DELETE(self, environ, start_response):
"""
@see: http://www.webdav.org/specs/rfc4918.html#METHOD_DELETE
"""
path = environ["PATH_INFO"]
provider = self._davProvider
res = provider.get_resource_inst(path, environ)
# --- Check request preconditions -------------------------------------
if util.get_content_length(environ) != 0:
self._fail(
HTTP_MEDIATYPE_NOT_SUPPORTED,
"The server does not handle any body content.",
)
if res is None:
self._fail(HTTP_NOT_FOUND, path)
if res.is_collection:
# Delete over collection
# "The DELETE method on a collection MUST act as if a
# 'Depth: infinity' header was used on it. A client MUST NOT submit
# a Depth header with a DELETE on a collection with any value but
# infinity."
if environ.setdefault("HTTP_DEPTH", "infinity") != "infinity":
self._fail(
HTTP_BAD_REQUEST,
)
)
forceCloseConnection = True
# HOTFIX for Vista and Windows 7 (GC issue 13, issue 23)
# It seems that we must read *all* of the request body, otherwise
# clients may miss the response.
# For example Vista MiniRedir didn't understand a 401 response,
# when trying an anonymous PUT of big files. As a consequence, it
# doesn't retry with credentials and the file copy fails.
# (XP is fine however).
util.read_and_discard_input(environ)
# Make sure the socket is not reused, unless we are 100% sure all
# current input was consumed
if util.get_content_length(environ) != 0 and not environ.get(
"wsgidav.all_input_read"
):
_logger.warning(
"Input stream not completely consumed: closing connection."
)
forceCloseConnection = True
if forceCloseConnection and headerDict.get("connection") != "close":
_logger.warning("Adding 'Connection: close' header.")
response_headers.append(("Connection", "close"))
# Log request
if self.verbose >= 3:
userInfo = environ.get("wsgidav.auth.user_name")
if not userInfo:
userInfo = "(anonymous)"
def do_UNLOCK(self, environ, start_response):
"""
@see: http://www.webdav.org/specs/rfc4918.html#METHOD_UNLOCK
"""
path = environ["PATH_INFO"]
provider = self._davProvider
res = self._davProvider.get_resource_inst(path, environ)
lockMan = provider.lock_manager
if lockMan is None:
self._fail(HTTP_NOT_IMPLEMENTED, "This share does not support locking.")
elif util.get_content_length(environ) != 0:
self._fail(
HTTP_MEDIATYPE_NOT_SUPPORTED,
"The server does not handle any body content.",
)
elif res is None:
self._fail(HTTP_NOT_FOUND, path)
elif "HTTP_LOCK_TOKEN" not in environ:
self._fail(HTTP_BAD_REQUEST, "Missing lock token.")
self._evaluate_if_headers(res, environ)
lockToken = environ["HTTP_LOCK_TOKEN"].strip("<>")
refUrl = res.get_ref_url()
if not lockMan.is_url_locked_by_token(refUrl, lockToken):
self._fail(
def _send_resource(self, environ, start_response, is_head_method):
"""
If-Range
If the entity is unchanged, send me the part(s) that I am missing;
otherwise, send me the entire new entity
If-Range: "737060cd8c284d8af7ad3082f209582d"
@see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.27
"""
path = environ["PATH_INFO"]
res = self._davProvider.get_resource_inst(path, environ)
if util.get_content_length(environ) != 0:
self._fail(
HTTP_MEDIATYPE_NOT_SUPPORTED,
"The server does not handle any body content.",
)
elif environ.setdefault("HTTP_DEPTH", "0") != "0":
self._fail(HTTP_BAD_REQUEST, "Only Depth: 0 supported.")
elif res is None:
self._fail(HTTP_NOT_FOUND, path)
elif res.is_collection:
self._fail(
HTTP_FORBIDDEN,
"Directory browsing is not enabled."
"(to enable it put WsgiDavDirBrowser into middleware_stack"
"option and set dir_browser -> enabled = True option.)",
)