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)

        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,
                    "Only Depth: infinity is supported for collections.",
                )
        else:
            if not environ.setdefault("HTTP_DEPTH", "0") in ("0", "infinity"):
                self._fail(
                    HTTP_BAD_REQUEST,
                    "Only Depth: 0 or infinity are supported for non-collections.",
                )

        self._evaluate_if_headers(res, environ)
        # We need write access on the parent collection. Also we check for
        # locked children
        parentRes = provider.get_resource_inst(util.get_uri_parent(path), environ)
        if parentRes:
            #            self._check_write_permission(parentRes, environ["HTTP_DEPTH"], environ)
            self._check_write_permission(parentRes, "0", environ)
        else:
            #            self._check_write_permission(res, environ["HTTP_DEPTH"], environ)
            self._check_write_permission(res, "0", environ)

        # --- Let provider handle the request natively ------------------------

        # Errors in deletion; [ (<ref-url>, <DAVError>), ... ]
        error_list = []

        try:
            handled = res.handle_delete()
            assert handled in (True, False) or type(handled) is list
            if type(handled) is list:
                error_list = handled
                handled = True
        except Exception as e:
            error_list = [(res.get_href(), as_DAVError(e))]
            handled = True
        if handled:
            return self._send_response(
                environ, start_response, res, HTTP_NO_CONTENT, error_list
            )

        # --- Let provider implement own recursion ----------------------------

        # Get a list of all resources (parents after children, so we can remove
        # them in that order)
        reverseChildList = res.get_descendants(
            depth_first=True, depth=environ["HTTP_DEPTH"], add_self=True
        )

        if res.is_collection and res.support_recursive_delete():
            hasConflicts = False
            for childRes in reverseChildList:
                try:
                    self._evaluate_if_headers(childRes, environ)
                    self._check_write_permission(childRes, "0", environ)
                except Exception:
                    hasConflicts = True
                    break

            if not hasConflicts:
                try:
                    error_list = res.delete()
                except Exception as e:
                    error_list = [(res.get_href(), as_DAVError(e))]
                return self._send_response(
                    environ, start_response, res, HTTP_NO_CONTENT, error_list
                )

        # --- Implement file-by-file processing -------------------------------

        # Hidden paths (ancestors of failed deletes) {<path>: True, ...}
        ignoreDict = {}
        for childRes in reverseChildList:
            if childRes.path in ignoreDict:
                _logger.debug(
                    "Skipping {} (contains error child)".format(childRes.path)
                )
                ignoreDict[util.get_uri_parent(childRes.path)] = ""
                continue

            try:
                # 9.6.1.: Any headers included with delete must be applied in
                #         processing every resource to be deleted
                self._evaluate_if_headers(childRes, environ)
                self._check_write_permission(childRes, "0", environ)
                childRes.delete()
                # Double-check, if deletion succeeded
                if provider.exists(childRes.path, environ):
                    raise DAVError(
                        HTTP_INTERNAL_ERROR, "Resource could not be deleted."
                    )
            except Exception as e:
                error_list.append((childRes.get_href(), as_DAVError(e)))
                ignoreDict[util.get_uri_parent(childRes.path)] = True

        # --- Send response ---------------------------------------------------

        return self._send_response(
            environ, start_response, res, HTTP_NO_CONTENT, error_list
        )
def do_DELETE ( self , environ , start_response ) : path = environ [ "PATH_INFO" ] provider = self . _davProvider res = provider . 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." , ) if res is None : self . _fail ( HTTP_NOT_FOUND ) if res . is_collection : if environ . setdefault ( "HTTP_DEPTH" , "infinity" ) != "infinity" : self . _fail ( HTTP_BAD_REQUEST , "Only Depth: infinity is supported for collections." , ) else : if not environ . setdefault ( "HTTP_DEPTH" , "0" ) in ( "0" , "infinity" ) : self . _fail ( HTTP_BAD_REQUEST , "Only Depth: 0 or infinity are supported for non-collections." , ) self . _evaluate_if_headers ( res , environ ) parentRes = provider . get_resource_inst ( util . get_uri_parent ( path ) , environ ) if parentRes : self . _check_write_permission ( parentRes , "0" , environ ) else : self . _check_write_permission ( res , "0" , environ ) error_list = [ ] try : handled = res . handle_delete ( ) assert handled in ( True , False ) or type ( handled ) is list if type ( handled ) is list : error_list = handled handled = True except Exception as e : error_list = [ ( res . get_href ( ) , as_DAVError ( e ) ) ] handled = True if handled : return self . _send_response ( environ , start_response , res , HTTP_NO_CONTENT , error_list ) reverseChildList = res . get_descendants ( depth_first = True , depth = environ [ "HTTP_DEPTH" ] , add_self = True ) if res . is_collection and res . support_recursive_delete ( ) : hasConflicts = False for childRes in reverseChildList : try : self . _evaluate_if_headers ( childRes , environ ) self . _check_write_permission ( childRes , "0" , environ ) except Exception : hasConflicts = True break if not hasConflicts : try : error_list = res . delete ( ) except Exception as e : error_list = [ ( res . get_href ( ) , as_DAVError ( e ) ) ] return self . _send_response ( environ , start_response , res , HTTP_NO_CONTENT , error_list ) ignoreDict = { } for childRes in reverseChildList : if childRes . path in ignoreDict : _logger . debug ( "Skipping {} (contains error child)" . format ( childRes . path ) ) ignoreDict [ util . get_uri_parent ( childRes . path ) ] = "" continue try : self . _evaluate_if_headers ( childRes , environ ) self . _check_write_permission ( childRes , "0" , environ ) childRes . delete ( ) if provider . exists ( childRes . path , environ ) : raise DAVError ( HTTP_INTERNAL_ERROR , "Resource could not be deleted." ) except Exception as e : error_list . append ( ( childRes . get_href ( ) , as_DAVError ( e ) ) ) ignoreDict [ util . get_uri_parent ( childRes . path ) ] = True return self . _send_response ( environ , start_response , res , HTTP_NO_CONTENT , error_list )
@see: http://www.webdav.org/specs/rfc4918.html#METHOD_DELETE