listReturn = []<EOL>seqRanges = rangetext.split("<STR_LIT:U+002C>")<EOL>for subrange in seqRanges:<EOL><INDENT>matched = False<EOL>if not matched:<EOL><INDENT>mObj = reByteRangeSpecifier.search(subrange)<EOL>if mObj:<EOL><INDENT>firstpos = int(mObj.group(<NUM_LIT:2>))<EOL>if mObj.group(<NUM_LIT:3>) == "<STR_LIT>":<EOL><INDENT>lastpos = filesize - <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>lastpos = int(mObj.group(<NUM_LIT:3>))<EOL><DEDENT>if firstpos <= lastpos and firstpos < filesize:<EOL><INDENT>if lastpos >= filesize:<EOL><INDENT>lastpos = filesize - <NUM_LIT:1><EOL><DEDENT>listReturn.append((firstpos, lastpos))<EOL>matched = True<EOL><DEDENT><DEDENT><DEDENT>if not matched:<EOL><INDENT>mObj = reSuffixByteRangeSpecifier.search(subrange)<EOL>if mObj:<EOL><INDENT>firstpos = filesize - int(mObj.group(<NUM_LIT:2>))<EOL>if firstpos < <NUM_LIT:0>:<EOL><INDENT>firstpos = <NUM_LIT:0><EOL><DEDENT>lastpos = filesize - <NUM_LIT:1><EOL>listReturn.append((firstpos, lastpos))<EOL>matched = True<EOL><DEDENT><DEDENT><DEDENT>listReturn.sort()<EOL>listReturn2 = []<EOL>totallength = <NUM_LIT:0><EOL>while len(listReturn) > <NUM_LIT:0>:<EOL><INDENT>(rfirstpos, rlastpos) = listReturn.pop()<EOL>counter = len(listReturn)<EOL>while counter > <NUM_LIT:0>:<EOL><INDENT>(nfirstpos, nlastpos) = listReturn[counter - <NUM_LIT:1>]<EOL>if nlastpos < rfirstpos - <NUM_LIT:1> or nfirstpos > nlastpos + <NUM_LIT:1>:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>rfirstpos = min(rfirstpos, nfirstpos)<EOL>rlastpos = max(rlastpos, nlastpos)<EOL>del listReturn[counter - <NUM_LIT:1>]<EOL><DEDENT>counter = counter - <NUM_LIT:1><EOL><DEDENT>listReturn2.append((rfirstpos, rlastpos, rlastpos - rfirstpos + <NUM_LIT:1>))<EOL>totallength = totallength + rlastpos - rfirstpos + <NUM_LIT:1><EOL><DEDENT>return (listReturn2, totallength)<EOL>

returns tuple (list, value)

list
    content ranges as values to their parsed components in the tuple
    (seek_position/abs position of first byte, abs position of last byte, num_of_bytes_to_read)
value
    total length for Content-Length


timeoutsecs = <NUM_LIT:0><EOL>timeoutvaluelist = timeoutvalue.split("<STR_LIT:U+002C>")<EOL>for timeoutspec in timeoutvaluelist:<EOL><INDENT>timeoutspec = timeoutspec.strip()<EOL>if timeoutspec.lower() == "<STR_LIT>":<EOL><INDENT>return -<NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>listSR = reSecondsReader.findall(timeoutspec)<EOL>for secs in listSR:<EOL><INDENT>timeoutsecs = int(secs)<EOL>if timeoutsecs > MAX_FINITE_TIMEOUT_LIMIT:<EOL><INDENT>return -<NUM_LIT:1><EOL><DEDENT>if timeoutsecs != <NUM_LIT:0>:<EOL><INDENT>return timeoutsecs<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return None<EOL>

Return -1 if infinite, else return numofsecs.


def evaluate_http_conditionals(dav_res, last_modified, entitytag, environ):

if not dav_res:<EOL><INDENT>return<EOL><DEDENT>if "<STR_LIT>" in environ and dav_res.support_etag():<EOL><INDENT>ifmatchlist = environ["<STR_LIT>"].split("<STR_LIT:U+002C>")<EOL>for ifmatchtag in ifmatchlist:<EOL><INDENT>ifmatchtag = ifmatchtag.strip('<STR_LIT>')<EOL>if ifmatchtag == entitytag or ifmatchtag == "<STR_LIT:*>":<EOL><INDENT>break<EOL><DEDENT>raise DAVError(HTTP_PRECONDITION_FAILED, "<STR_LIT>")<EOL><DEDENT><DEDENT>ifModifiedSinceFailed = False<EOL>if "<STR_LIT>" in environ and dav_res.support_modified():<EOL><INDENT>ifmodtime = parse_time_string(environ["<STR_LIT>"])<EOL>if ifmodtime and ifmodtime > last_modified:<EOL><INDENT>ifModifiedSinceFailed = True<EOL><DEDENT><DEDENT>ignoreIfModifiedSince = False<EOL>if "<STR_LIT>" in environ and dav_res.support_etag():<EOL><INDENT>ifmatchlist = environ["<STR_LIT>"].split("<STR_LIT:U+002C>")<EOL>for ifmatchtag in ifmatchlist:<EOL><INDENT>ifmatchtag = ifmatchtag.strip('<STR_LIT>')<EOL>if ifmatchtag == entitytag or ifmatchtag == "<STR_LIT:*>":<EOL><INDENT>if (<EOL>environ["<STR_LIT>"] in ("<STR_LIT:GET>", "<STR_LIT>")<EOL>and not ifModifiedSinceFailed<EOL>):<EOL><INDENT>raise DAVError(HTTP_NOT_MODIFIED, "<STR_LIT>")<EOL><DEDENT>raise DAVError(<EOL>HTTP_PRECONDITION_FAILED, "<STR_LIT>"<EOL>)<EOL><DEDENT><DEDENT>ignoreIfModifiedSince = True<EOL><DEDENT>if "<STR_LIT>" in environ and dav_res.support_modified():<EOL><INDENT>ifunmodtime = parse_time_string(environ["<STR_LIT>"])<EOL>if ifunmodtime and ifunmodtime <= last_modified:<EOL><INDENT>raise DAVError(<EOL>HTTP_PRECONDITION_FAILED, "<STR_LIT>"<EOL>)<EOL><DEDENT><DEDENT>if ifModifiedSinceFailed and not ignoreIfModifiedSince:<EOL><INDENT>raise DAVError(HTTP_NOT_MODIFIED, "<STR_LIT>")<EOL><DEDENT>return<EOL>

Handle 'If-...:' headers (but not 'If:' header).

    If-Match
        @see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24
        Only perform the action if the client supplied entity matches the
        same entity on the server. This is mainly for methods like
        PUT to only update a resource if it has not been modified since the
        user last updated it.
        If-Match: "737060cd8c284d8af7ad3082f209582d"
    If-Modified-Since
        @see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25
        Allows a 304 Not Modified to be returned if content is unchanged
        If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
    If-None-Match
        @see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26
        Allows a 304 Not Modified to be returned if content is unchanged,
        see HTTP ETag
        If-None-Match: "737060cd8c284d8af7ad3082f209582d"
    If-Unmodified-Since
        @see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.28
        Only send the response if the entity has not been modified since a
        specific time.


if "<STR_LIT>" in environ:<EOL><INDENT>return<EOL><DEDENT>if "<STR_LIT>" not in environ:<EOL><INDENT>environ["<STR_LIT>"] = None<EOL>environ["<STR_LIT>"] = []<EOL>return<EOL><DEDENT>iftext = environ["<STR_LIT>"].strip()<EOL>if not iftext.startswith("<STR_LIT:<>"):<EOL><INDENT>iftext = "<STR_LIT>" + iftext<EOL><DEDENT>ifDict = dict([])<EOL>ifLockList = []<EOL>resource1 = "<STR_LIT:*>"<EOL>for (tmpURLVar, URLVar, _tmpContentVar, contentVar) in reIfSeparator.findall(<EOL>iftext<EOL>):<EOL><INDENT>if tmpURLVar != "<STR_LIT>":<EOL><INDENT>resource1 = URLVar<EOL><DEDENT>else:<EOL><INDENT>listTagContents = []<EOL>testflag = True<EOL>for listitem in reIfTagListContents.findall(contentVar):<EOL><INDENT>if listitem.upper() != "<STR_LIT>":<EOL><INDENT>if listitem.startswith("<STR_LIT:[>"):<EOL><INDENT>listTagContents.append(<EOL>(testflag, "<STR_LIT>", listitem.strip('<STR_LIT>'))<EOL>)<EOL><DEDENT>else:<EOL><INDENT>listTagContents.append(<EOL>(testflag, "<STR_LIT>", listitem.strip("<STR_LIT>"))<EOL>)<EOL>ifLockList.append(listitem.strip("<STR_LIT>"))<EOL><DEDENT><DEDENT>testflag = listitem.upper() != "<STR_LIT>"<EOL><DEDENT>if resource1 in ifDict:<EOL><INDENT>listTag = ifDict[resource1]<EOL><DEDENT>else:<EOL><INDENT>listTag = []<EOL>ifDict[resource1] = listTag<EOL><DEDENT>listTag.append(listTagContents)<EOL><DEDENT><DEDENT>environ["<STR_LIT>"] = ifDict<EOL>environ["<STR_LIT>"] = ifLockList<EOL>_logger.debug("<STR_LIT>".format(pformat(ifDict)))<EOL>return<EOL>

Parse HTTP_IF header into a dictionary and lists, and cache the result.

    @see http://www.webdav.org/specs/rfc4918.html#HEADER_If


(mimetype, _mimeencoding) = mimetypes.guess_type(url)<EOL>if not mimetype:<EOL><INDENT>ext = os.path.splitext(url)[<NUM_LIT:1>]<EOL>mimetype = _MIME_TYPES.get(ext)<EOL>_logger.debug("<STR_LIT>".format(url, mimetype))<EOL><DEDENT>if not mimetype:<EOL><INDENT>mimetype = "<STR_LIT>"<EOL><DEDENT>return mimetype<EOL>

Use the mimetypes module to lookup the type for an extension.

    This function also adds some extensions required for HTML5


assert DOT_ESCAPE not in s<EOL>return s.replace("<STR_LIT:.>", DOT_ESCAPE)<EOL>

Return an encoded version of `s` that may be used as MongoDB key.


return key.replace(DOT_ESCAPE, "<STR_LIT:.>")<EOL>

Decode a string that was encoded by encode_mongo_key().


<EOL>vr = self.db.view("<STR_LIT>", key=url, include_docs=True)<EOL>_logger.debug("<STR_LIT>" % (url, len(vr)))<EOL>assert len(vr) <= <NUM_LIT:1>, "<STR_LIT>" % url<EOL>for row in vr:<EOL><INDENT>assert row.doc<EOL>return row.doc<EOL><DEDENT>return None<EOL>


<EOL>map_fun = """<STR_LIT>""" % (<EOL>url + "<STR_LIT:/>"<EOL>)<EOL>vr = self.db.query(map_fun, include_docs=True)<EOL>for row in vr:<EOL><INDENT>yield row.doc<EOL><DEDENT>return<EOL>

Return properties document for url and all children.


def remove_property(self, norm_url, name, dry_run=False, environ=None):

_logger.debug(<EOL>"<STR_LIT>".format(norm_url, name, dry_run)<EOL>)<EOL>if dry_run:<EOL><INDENT>return<EOL><DEDENT>self._lock.acquire_write()<EOL>try:<EOL><INDENT>if not self._loaded:<EOL><INDENT>self._lazy_open()<EOL><DEDENT>if norm_url in self._dict:<EOL><INDENT>locatordict = self._dict[norm_url]<EOL>if name in locatordict:<EOL><INDENT>del locatordict[name]<EOL>self._dict[norm_url] = locatordict<EOL>self._sync()<EOL><DEDENT><DEDENT>if __debug__ and self._verbose >= <NUM_LIT:4>:<EOL><INDENT>self._check()<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>self._lock.release()<EOL><DEDENT>

Specifying the removal of a property that does not exist is NOT an error.


self._lock.acquire_write()<EOL>try:<EOL><INDENT>was_closed = self._dict is None<EOL>if was_closed:<EOL><INDENT>self.open()<EOL><DEDENT>if len(self._dict):<EOL><INDENT>self._dict.clear()<EOL>self._dict.sync()<EOL><DEDENT>if was_closed:<EOL><INDENT>self.close()<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>self._lock.release()<EOL><DEDENT>


res = self.unread<EOL>self.unread = "<STR_LIT>"<EOL>while res == "<STR_LIT>" or size < <NUM_LIT:0> or (size > <NUM_LIT:0> and len(res) < size):<EOL><INDENT>try:<EOL><INDENT>res += compat.to_native(self.queue.get(True, <NUM_LIT:0.1>))<EOL><DEDENT>except compat.queue.Empty:<EOL><INDENT>if self.is_closed:<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT>if size > <NUM_LIT:0> and len(res) > size:<EOL><INDENT>self.unread = res[size:]<EOL>res = res[:size]<EOL><DEDENT>return res<EOL>

Read a chunk of bytes from queue.

        size = 0: Read next chunk (arbitrary length)
             > 0: Read one chunk of `size` bytes (or less if stream was closed)
             < 0: Read all bytes as single chunk (i.e. blocks until stream is closed)

        This method blocks until the requested size become available.
        However, if close() was called, '' is returned immediately.


if self.is_closed:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if compat.is_basestring(chunk):<EOL><INDENT>self.queue.put(chunk)<EOL><DEDENT>else:  <EOL><INDENT>for o in chunk:<EOL><INDENT>self.queue.put(o)<EOL><DEDENT><DEDENT>

Put a chunk of bytes (or an iterable) to the queue.

        May block if max_size number of chunks is reached.


self.data_stream = data_stream<EOL>self.buffer = "<STR_LIT>"<EOL>

Intialise the object with the data stream.


while size is None or len(self.buffer) < size:<EOL><INDENT>try:<EOL><INDENT>self.buffer += next(self.data_stream)<EOL><DEDENT>except StopIteration:<EOL><INDENT>break<EOL><DEDENT><DEDENT>sized_chunk = self.buffer[:size]<EOL>if size is None:<EOL><INDENT>self.buffer = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>self.buffer = self.buffer[size:]<EOL><DEDENT>return sized_chunk<EOL>


def _fail(self, value, context_info=None, src_exception=None, err_condition=None):

e = DAVError(value, context_info, src_exception, err_condition)<EOL>if self.verbose >= <NUM_LIT:4>:<EOL><INDENT>_logger.warning(<EOL>"<STR_LIT>".format(<EOL>safe_re_encode(e.get_user_info(), sys.stdout.encoding)<EOL>)<EOL>)<EOL><DEDENT>raise e<EOL>


def _get_context(self, environ, dav_res):

assert dav_res.is_collection<EOL>is_readonly = environ["<STR_LIT>"].is_readonly()<EOL>context = {<EOL>"<STR_LIT>": (self.config.get("<STR_LIT>") or "<STR_LIT>") + ASSET_SHARE,<EOL>"<STR_LIT>": [],<EOL>"<STR_LIT:version>": __version__,<EOL>"<STR_LIT>": compat.unquote(dav_res.get_href()),<EOL>"<STR_LIT:url>": dav_res.get_href(),  <EOL>"<STR_LIT>": util.get_uri_parent(dav_res.get_href()),<EOL>"<STR_LIT>": self.dir_config,<EOL>"<STR_LIT>": is_readonly,<EOL>"<STR_LIT>": "<STR_LIT>" if is_readonly else "<STR_LIT>",<EOL>"<STR_LIT>": False,<EOL>}<EOL>trailer = self.dir_config.get("<STR_LIT>")<EOL>if trailer is True:<EOL><INDENT>trailer = "<STR_LIT>"<EOL><DEDENT>if trailer:<EOL><INDENT>trailer = trailer.replace(<EOL>"<STR_LIT>",<EOL>"<STR_LIT>".format(<EOL>__version__<EOL>),<EOL>)<EOL>trailer = trailer.replace("<STR_LIT>", util.get_rfc1123_time())<EOL><DEDENT>context["<STR_LIT>"] = trailer<EOL>rows = context["<STR_LIT>"]<EOL>dirInfoList = dav_res.get_directory_info()<EOL>if dirInfoList is None:<EOL><INDENT>dirInfoList = []<EOL>childList = dav_res.get_descendants(depth="<STR_LIT:1>", add_self=False)<EOL>for res in childList:<EOL><INDENT>di = res.get_display_info()<EOL>href = res.get_href()<EOL>ofe_prefix = None<EOL>tr_classes = []<EOL>a_classes = []<EOL>if res.is_collection:<EOL><INDENT>tr_classes.append("<STR_LIT>")<EOL><DEDENT>if not is_readonly and not res.is_collection:<EOL><INDENT>ext = os.path.splitext(href)[<NUM_LIT:1>].lstrip("<STR_LIT:.>").lower()<EOL>officeType = msOfficeExtToTypeMap.get(ext)<EOL>if officeType:<EOL><INDENT>if self.dir_config.get("<STR_LIT>"):<EOL><INDENT>ofe_prefix = "<STR_LIT>".format(officeType)<EOL>a_classes.append("<STR_LIT>")<EOL><DEDENT><DEDENT><DEDENT>entry = {<EOL>"<STR_LIT>": href,<EOL>"<STR_LIT>": ofe_prefix,<EOL>"<STR_LIT>": "<STR_LIT:U+0020>".join(a_classes),<EOL>"<STR_LIT>": "<STR_LIT:U+0020>".join(tr_classes),<EOL>"<STR_LIT>": res.get_display_name(),<EOL>"<STR_LIT>": res.get_last_modified(),<EOL>"<STR_LIT>": res.is_collection,<EOL>"<STR_LIT>": res.get_content_length(),<EOL>"<STR_LIT>": di.get("<STR_LIT:type>"),<EOL>"<STR_LIT>": di.get("<STR_LIT>"),<EOL>}<EOL>dirInfoList.append(entry)<EOL><DEDENT><DEDENT>ignore_patterns = self.dir_config.get("<STR_LIT:ignore>", [])<EOL>if compat.is_basestring(ignore_patterns):<EOL><INDENT>ignore_patterns = ignore_patterns.split("<STR_LIT:U+002C>")<EOL><DEDENT>ignored_list = []<EOL>for entry in dirInfoList:<EOL><INDENT>ignore = False<EOL>for pat in ignore_patterns:<EOL><INDENT>if fnmatch(entry["<STR_LIT>"], pat):<EOL><INDENT>ignored_list.append(entry["<STR_LIT>"])<EOL>ignore = True<EOL>break<EOL><DEDENT><DEDENT>if ignore:<EOL><INDENT>continue<EOL><DEDENT>last_modified = entry.get("<STR_LIT>")<EOL>if last_modified is None:<EOL><INDENT>entry["<STR_LIT>"] = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>entry["<STR_LIT>"] = util.get_rfc1123_time(last_modified)<EOL><DEDENT>entry["<STR_LIT>"] = "<STR_LIT:->"<EOL>if not entry.get("<STR_LIT>"):<EOL><INDENT>content_length = entry.get("<STR_LIT>")<EOL>if content_length is not None:<EOL><INDENT>entry["<STR_LIT>"] = util.byte_number_string(content_length)<EOL><DEDENT><DEDENT>rows.append(entry)<EOL><DEDENT>if ignored_list:<EOL><INDENT>_logger.debug(<EOL>"<STR_LIT>".format(<EOL>len(ignored_list), ignored_list<EOL>)<EOL>)<EOL><DEDENT>sort = "<STR_LIT:name>"<EOL>if sort == "<STR_LIT:name>":<EOL><INDENT>rows.sort(<EOL>key=lambda v: "<STR_LIT>".format(<EOL>not v["<STR_LIT>"], v["<STR_LIT>"].lower()<EOL>)<EOL>)<EOL><DEDENT>if "<STR_LIT>" in environ:<EOL><INDENT>context.update(<EOL>{<EOL>"<STR_LIT>": True,<EOL>"<STR_LIT>": (environ.get("<STR_LIT>") or "<STR_LIT>"),<EOL>"<STR_LIT>": environ.get("<STR_LIT>"),<EOL>"<STR_LIT>": "<STR_LIT:U+002CU+0020>".join(environ.get("<STR_LIT>") or []),<EOL>"<STR_LIT>": "<STR_LIT:U+002CU+0020>".join(<EOL>environ.get("<STR_LIT>") or []<EOL>),<EOL>}<EOL>)<EOL><DEDENT>return context<EOL>


util.fail(value, context_info, src_exception, err_condition)<EOL>


def _send_response(<EOL>self, environ, start_response, root_res, success_code, error_list<EOL>):

assert success_code in (HTTP_CREATED, HTTP_NO_CONTENT, HTTP_OK)<EOL>if not error_list:<EOL><INDENT>return util.send_status_response(environ, start_response, success_code)<EOL><DEDENT>if len(error_list) == <NUM_LIT:1> and error_list[<NUM_LIT:0>][<NUM_LIT:0>] == root_res.get_href():<EOL><INDENT>return util.send_status_response(environ, start_response, error_list[<NUM_LIT:0>][<NUM_LIT:1>])<EOL><DEDENT>multistatusEL = xml_tools.make_multistatus_el()<EOL>for refurl, e in error_list:<EOL><INDENT>assert refurl.startswith("<STR_LIT:/>")<EOL>assert isinstance(e, DAVError)<EOL>responseEL = etree.SubElement(multistatusEL, "<STR_LIT>")<EOL>etree.SubElement(responseEL, "<STR_LIT>").text = refurl<EOL>etree.SubElement(responseEL, "<STR_LIT>").text = "<STR_LIT>".format(<EOL>get_http_status_string(e)<EOL>)<EOL><DEDENT>return util.send_multi_status_response(environ, start_response, multistatusEL)<EOL>

Send WSGI response (single or multistatus).

        - If error_list is None or [], then <success_code> is send as response.
        - If error_list contains a single error with a URL that matches root_res,
          then this error is returned.
        - If error_list contains more than one error, then '207 Multi-Status' is
          returned.


def _check_write_permission(self, res, depth, environ):

lockMan = self._davProvider.lock_manager<EOL>if lockMan is None or res is None:<EOL><INDENT>return True<EOL><DEDENT>refUrl = res.get_ref_url()<EOL>if "<STR_LIT>" not in environ:<EOL><INDENT>util.parse_if_header_dict(environ)<EOL><DEDENT>lockMan.check_write_permission(<EOL>refUrl,<EOL>depth,<EOL>environ["<STR_LIT>"],<EOL>environ["<STR_LIT>"],<EOL>)<EOL>

Raise DAVError(HTTP_LOCKED), if res is locked.

        If depth=='infinity', we also raise when child resources are locked.


def _evaluate_if_headers(self, res, environ):

<EOL>if "<STR_LIT>" not in environ:<EOL><INDENT>util.parse_if_header_dict(environ)<EOL><DEDENT>if res is None:<EOL><INDENT>return<EOL><DEDENT>ifDict = environ["<STR_LIT>"]<EOL>last_modified = -<NUM_LIT:1>  <EOL>entitytag = "<STR_LIT>"  <EOL>if res.get_last_modified() is not None:<EOL><INDENT>last_modified = res.get_last_modified()<EOL><DEDENT>if res.get_etag() is not None:<EOL><INDENT>entitytag = res.get_etag()<EOL><DEDENT>if (<EOL>"<STR_LIT>" in environ<EOL>or "<STR_LIT>" in environ<EOL>or "<STR_LIT>" in environ<EOL>or "<STR_LIT>" in environ<EOL>):<EOL><INDENT>util.evaluate_http_conditionals(res, last_modified, entitytag, environ)<EOL><DEDENT>if "<STR_LIT>" not in environ:<EOL><INDENT>return<EOL><DEDENT>refUrl = res.get_ref_url()<EOL>lockMan = self._davProvider.lock_manager<EOL>locktokenlist = []<EOL>if lockMan:<EOL><INDENT>lockList = lockMan.get_indirect_url_lock_list(<EOL>refUrl, environ["<STR_LIT>"]<EOL>)<EOL>for lock in lockList:<EOL><INDENT>locktokenlist.append(lock["<STR_LIT>"])<EOL><DEDENT><DEDENT>if not util.test_if_header_dict(res, ifDict, refUrl, locktokenlist, entitytag):<EOL><INDENT>self._fail(HTTP_PRECONDITION_FAILED, "<STR_LIT>")<EOL><DEDENT>return<EOL>

Apply HTTP headers on <path>, raising DAVError if conditions fail.

        Add environ['wsgidav.conditions.if'] and environ['wsgidav.ifLockTokenList'].
        Handle these headers:

          - If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since:
            Raising HTTP_PRECONDITION_FAILED or HTTP_NOT_MODIFIED
          - If:
            Raising HTTP_PRECONDITION_FAILED

        @see http://www.webdav.org/specs/rfc4918.html#HEADER_If
        @see util.evaluate_http_conditionals


def do_PROPFIND(self, environ, start_response):

path = environ["<STR_LIT>"]<EOL>res = self._davProvider.get_resource_inst(path, environ)<EOL>environ.setdefault("<STR_LIT>", "<STR_LIT>")<EOL>if not environ["<STR_LIT>"] in ("<STR_LIT:0>", "<STR_LIT:1>", "<STR_LIT>"):<EOL><INDENT>self._fail(<EOL>HTTP_BAD_REQUEST,<EOL>"<STR_LIT>".format(environ["<STR_LIT>"]),<EOL>)<EOL><DEDENT>if environ["<STR_LIT>"] == "<STR_LIT>" and not self.allow_propfind_infinite:<EOL><INDENT>self._fail(<EOL>HTTP_FORBIDDEN,<EOL>"<STR_LIT>",<EOL>err_condition=PRECONDITION_CODE_PropfindFiniteDepth,<EOL>)<EOL><DEDENT>if res is None:<EOL><INDENT>self._fail(HTTP_NOT_FOUND)<EOL><DEDENT>if environ.get("<STR_LIT>"):<EOL><INDENT>pass  <EOL><DEDENT>self._evaluate_if_headers(res, environ)<EOL>requestEL = util.parse_xml_body(environ, allow_empty=True)<EOL>if requestEL is None:<EOL><INDENT>requestEL = etree.XML(<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>if requestEL.tag != "<STR_LIT>":<EOL><INDENT>self._fail(HTTP_BAD_REQUEST)<EOL><DEDENT>propNameList = []<EOL>propFindMode = None<EOL>for pfnode in requestEL:<EOL><INDENT>if pfnode.tag == "<STR_LIT>":<EOL><INDENT>if propFindMode:<EOL><INDENT>self._fail(HTTP_BAD_REQUEST)<EOL><DEDENT>propFindMode = "<STR_LIT>"<EOL><DEDENT>elif pfnode.tag == "<STR_LIT>":<EOL><INDENT>if propFindMode:  <EOL><INDENT>self._fail(HTTP_BAD_REQUEST)<EOL><DEDENT>propFindMode = "<STR_LIT:name>"<EOL><DEDENT>elif pfnode.tag == "<STR_LIT>":<EOL><INDENT>if propFindMode not in (None, "<STR_LIT>"):<EOL><INDENT>self._fail(HTTP_BAD_REQUEST)<EOL><DEDENT>propFindMode = "<STR_LIT>"<EOL>for pfpnode in pfnode:<EOL><INDENT>propNameList.append(pfpnode.tag)<EOL><DEDENT><DEDENT><DEDENT>reslist = res.get_descendants(depth=environ["<STR_LIT>"], add_self=True)<EOL>multistatusEL = xml_tools.make_multistatus_el()<EOL>responsedescription = []<EOL>for child in reslist:<EOL><INDENT>if propFindMode == "<STR_LIT>":<EOL><INDENT>propList = child.get_properties("<STR_LIT>")<EOL><DEDENT>elif propFindMode == "<STR_LIT:name>":<EOL><INDENT>propList = child.get_properties("<STR_LIT:name>")<EOL><DEDENT>else:<EOL><INDENT>propList = child.get_properties("<STR_LIT>", name_list=propNameList)<EOL><DEDENT>href = child.get_href()<EOL>util.add_property_response(multistatusEL, href, propList)<EOL><DEDENT>if responsedescription:<EOL><INDENT>etree.SubElement(<EOL>multistatusEL, "<STR_LIT>"<EOL>).text = "<STR_LIT:\n>".join(responsedescription)<EOL><DEDENT>return util.send_multi_status_response(environ, start_response, multistatusEL)<EOL>

TODO: does not yet support If and If HTTP Conditions
@see http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND


def do_PROPPATCH(self, environ, start_response):

path = environ["<STR_LIT>"]<EOL>res = self._davProvider.get_resource_inst(path, environ)<EOL>environ.setdefault("<STR_LIT>", "<STR_LIT:0>")<EOL>if environ["<STR_LIT>"] != "<STR_LIT:0>":<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>if res is None:<EOL><INDENT>self._fail(HTTP_NOT_FOUND)<EOL><DEDENT>self._evaluate_if_headers(res, environ)<EOL>self._check_write_permission(res, "<STR_LIT:0>", environ)<EOL>requestEL = util.parse_xml_body(environ)<EOL>if requestEL.tag != "<STR_LIT>":<EOL><INDENT>self._fail(HTTP_BAD_REQUEST)<EOL><DEDENT>propupdatelist = []<EOL>for ppnode in requestEL:<EOL><INDENT>propupdatemethod = None<EOL>if ppnode.tag == "<STR_LIT>":<EOL><INDENT>propupdatemethod = "<STR_LIT>"<EOL><DEDENT>elif ppnode.tag == "<STR_LIT>":<EOL><INDENT>propupdatemethod = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>self._fail(<EOL>HTTP_BAD_REQUEST, "<STR_LIT>"<EOL>)<EOL><DEDENT>for propnode in ppnode:<EOL><INDENT>if propnode.tag != "<STR_LIT>":<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>for propertynode in propnode:<EOL><INDENT>propvalue = None<EOL>if propupdatemethod == "<STR_LIT>":<EOL><INDENT>propvalue = None  <EOL>if len(propertynode) > <NUM_LIT:0>:<EOL><INDENT>self._fail(<EOL>HTTP_BAD_REQUEST,<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>propvalue = propertynode<EOL><DEDENT>propupdatelist.append((propertynode.tag, propvalue))<EOL><DEDENT><DEDENT><DEDENT>successflag = True<EOL>writeresultlist = []<EOL>for (name, propvalue) in propupdatelist:<EOL><INDENT>try:<EOL><INDENT>res.set_property_value(name, propvalue, dry_run=True)<EOL><DEDENT>except Exception as e:<EOL><INDENT>writeresult = as_DAVError(e)<EOL><DEDENT>else:<EOL><INDENT>writeresult = "<STR_LIT>"<EOL><DEDENT>writeresultlist.append((name, writeresult))<EOL>successflag = successflag and writeresult == "<STR_LIT>"<EOL><DEDENT>propResponseList = []<EOL>responsedescription = []<EOL>if not successflag:<EOL><INDENT>for (name, result) in writeresultlist:<EOL><INDENT>if result == "<STR_LIT>":<EOL><INDENT>result = DAVError(HTTP_FAILED_DEPENDENCY)<EOL><DEDENT>elif isinstance(result, DAVError):<EOL><INDENT>responsedescription.append(result.get_user_info())<EOL><DEDENT>propResponseList.append((name, result))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for (name, propvalue) in propupdatelist:<EOL><INDENT>try:<EOL><INDENT>res.set_property_value(name, propvalue, dry_run=False)<EOL>propResponseList.append((name, None))<EOL><DEDENT>except Exception as e:<EOL><INDENT>e = as_DAVError(e)<EOL>propResponseList.append((name, e))<EOL>responsedescription.append(e.get_user_info())<EOL><DEDENT><DEDENT><DEDENT>multistatusEL = xml_tools.make_multistatus_el()<EOL>href = res.get_href()<EOL>util.add_property_response(multistatusEL, href, propResponseList)<EOL>if responsedescription:<EOL><INDENT>etree.SubElement(<EOL>multistatusEL, "<STR_LIT>"<EOL>).text = "<STR_LIT:\n>".join(responsedescription)<EOL><DEDENT>return util.send_multi_status_response(environ, start_response, multistatusEL)<EOL>

Handle PROPPATCH request to set or remove a property.

        @see http://www.webdav.org/specs/rfc4918.html#METHOD_PROPPATCH


def do_MKCOL(self, environ, start_response):

path = environ["<STR_LIT>"]<EOL>provider = self._davProvider<EOL>if util.get_content_length(environ) != <NUM_LIT:0>:<EOL><INDENT>self._fail(<EOL>HTTP_MEDIATYPE_NOT_SUPPORTED,<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT>if environ.setdefault("<STR_LIT>", "<STR_LIT:0>") != "<STR_LIT:0>":<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>if provider.exists(path, environ):<EOL><INDENT>self._fail(<EOL>HTTP_METHOD_NOT_ALLOWED,<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT>parentRes = provider.get_resource_inst(util.get_uri_parent(path), environ)<EOL>if not parentRes or not parentRes.is_collection:<EOL><INDENT>self._fail(HTTP_CONFLICT, "<STR_LIT>")<EOL><DEDENT>self._check_write_permission(parentRes, "<STR_LIT:0>", environ)<EOL>parentRes.create_collection(util.get_uri_name(path))<EOL>return util.send_status_response(environ, start_response, HTTP_CREATED)<EOL>

Handle MKCOL request to create a new collection.

        @see http://www.webdav.org/specs/rfc4918.html#METHOD_MKCOL


def do_POST(self, environ, start_response):

self._fail(HTTP_METHOD_NOT_ALLOWED)<EOL>

@see http://www.webdav.org/specs/rfc4918.html#METHOD_POST
@see http://stackoverflow.com/a/22606899/19166


def do_DELETE(self, environ, start_response):

path = environ["<STR_LIT>"]<EOL>provider = self._davProvider<EOL>res = provider.get_resource_inst(path, environ)<EOL>if util.get_content_length(environ) != <NUM_LIT:0>:<EOL><INDENT>self._fail(<EOL>HTTP_MEDIATYPE_NOT_SUPPORTED,<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT>if res is None:<EOL><INDENT>self._fail(HTTP_NOT_FOUND)<EOL><DEDENT>if res.is_collection:<EOL><INDENT>if environ.setdefault("<STR_LIT>", "<STR_LIT>") != "<STR_LIT>":<EOL><INDENT>self._fail(<EOL>HTTP_BAD_REQUEST,<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if not environ.setdefault("<STR_LIT>", "<STR_LIT:0>") in ("<STR_LIT:0>", "<STR_LIT>"):<EOL><INDENT>self._fail(<EOL>HTTP_BAD_REQUEST,<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT><DEDENT>self._evaluate_if_headers(res, environ)<EOL>parentRes = provider.get_resource_inst(util.get_uri_parent(path), environ)<EOL>if parentRes:<EOL><INDENT>self._check_write_permission(parentRes, "<STR_LIT:0>", environ)<EOL><DEDENT>else:<EOL><INDENT>self._check_write_permission(res, "<STR_LIT:0>", environ)<EOL><DEDENT>error_list = []<EOL>try:<EOL><INDENT>handled = res.handle_delete()<EOL>assert handled in (True, False) or type(handled) is list<EOL>if type(handled) is list:<EOL><INDENT>error_list = handled<EOL>handled = True<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>error_list = [(res.get_href(), as_DAVError(e))]<EOL>handled = True<EOL><DEDENT>if handled:<EOL><INDENT>return self._send_response(<EOL>environ, start_response, res, HTTP_NO_CONTENT, error_list<EOL>)<EOL><DEDENT>reverseChildList = res.get_descendants(<EOL>depth_first=True, depth=environ["<STR_LIT>"], add_self=True<EOL>)<EOL>if res.is_collection and res.support_recursive_delete():<EOL><INDENT>hasConflicts = False<EOL>for childRes in reverseChildList:<EOL><INDENT>try:<EOL><INDENT>self._evaluate_if_headers(childRes, environ)<EOL>self._check_write_permission(childRes, "<STR_LIT:0>", environ)<EOL><DEDENT>except Exception:<EOL><INDENT>hasConflicts = True<EOL>break<EOL><DEDENT><DEDENT>if not hasConflicts:<EOL><INDENT>try:<EOL><INDENT>error_list = res.delete()<EOL><DEDENT>except Exception as e:<EOL><INDENT>error_list = [(res.get_href(), as_DAVError(e))]<EOL><DEDENT>return self._send_response(<EOL>environ, start_response, res, HTTP_NO_CONTENT, error_list<EOL>)<EOL><DEDENT><DEDENT>ignoreDict = {}<EOL>for childRes in reverseChildList:<EOL><INDENT>if childRes.path in ignoreDict:<EOL><INDENT>_logger.debug(<EOL>"<STR_LIT>".format(childRes.path)<EOL>)<EOL>ignoreDict[util.get_uri_parent(childRes.path)] = "<STR_LIT>"<EOL>continue<EOL><DEDENT>try:<EOL><INDENT>self._evaluate_if_headers(childRes, environ)<EOL>self._check_write_permission(childRes, "<STR_LIT:0>", environ)<EOL>childRes.delete()<EOL>if provider.exists(childRes.path, environ):<EOL><INDENT>raise DAVError(<EOL>HTTP_INTERNAL_ERROR, "<STR_LIT>"<EOL>)<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>error_list.append((childRes.get_href(), as_DAVError(e)))<EOL>ignoreDict[util.get_uri_parent(childRes.path)] = True<EOL><DEDENT><DEDENT>return self._send_response(<EOL>environ, start_response, res, HTTP_NO_CONTENT, error_list<EOL>)<EOL>


def _stream_data_chunked(self, environ, block_size):

<EOL>if "<STR_LIT>" in environ.get("<STR_LIT>", "<STR_LIT>") and environ.get(<EOL>"<STR_LIT>"<EOL>):<EOL><INDENT>WORKAROUND_CHUNK_LENGTH = True<EOL>buf = environ.get("<STR_LIT>", "<STR_LIT:0>")<EOL>length = int(buf)<EOL><DEDENT>else:<EOL><INDENT>WORKAROUND_CHUNK_LENGTH = False<EOL>buf = environ["<STR_LIT>"].readline()<EOL>environ["<STR_LIT>"] = <NUM_LIT:1><EOL>if buf == compat.b_empty:<EOL><INDENT>length = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>length = int(buf, <NUM_LIT:16>)<EOL><DEDENT><DEDENT>while length > <NUM_LIT:0>:<EOL><INDENT>buf = environ["<STR_LIT>"].read(block_size)<EOL>yield buf<EOL>if WORKAROUND_CHUNK_LENGTH:<EOL><INDENT>environ["<STR_LIT>"] = <NUM_LIT:1><EOL>if buf == compat.b_empty:<EOL><INDENT>length = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>length -= len(buf)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>environ["<STR_LIT>"].readline()<EOL>buf = environ["<STR_LIT>"].readline()<EOL>if buf == compat.b_empty:<EOL><INDENT>length = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>length = int(buf, <NUM_LIT:16>)<EOL><DEDENT><DEDENT><DEDENT>environ["<STR_LIT>"] = <NUM_LIT:1><EOL>


def _stream_data(self, environ, content_length, block_size):

if content_length == <NUM_LIT:0>:<EOL><INDENT>_logger.info("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>assert content_length > <NUM_LIT:0><EOL>contentremain = content_length<EOL>while contentremain > <NUM_LIT:0>:<EOL><INDENT>n = min(contentremain, block_size)<EOL>readbuffer = environ["<STR_LIT>"].read(n)<EOL>if not len(readbuffer) > <NUM_LIT:0>:<EOL><INDENT>_logger.error("<STR_LIT>".format(n))<EOL>break<EOL><DEDENT>environ["<STR_LIT>"] = <NUM_LIT:1><EOL>yield readbuffer<EOL>contentremain -= len(readbuffer)<EOL><DEDENT>if contentremain == <NUM_LIT:0>:<EOL><INDENT>environ["<STR_LIT>"] = <NUM_LIT:1><EOL><DEDENT><DEDENT>

Get the data from a non-chunked transfer.


def do_PUT(self, environ, start_response):

path = environ["<STR_LIT>"]<EOL>provider = self._davProvider<EOL>res = provider.get_resource_inst(path, environ)<EOL>parentRes = provider.get_resource_inst(util.get_uri_parent(path), environ)<EOL>isnewfile = res is None<EOL>if "<STR_LIT>" in environ:<EOL><INDENT>util.fail(HTTP_NOT_IMPLEMENTED, "<STR_LIT>")<EOL><DEDENT>if "<STR_LIT>" in environ:<EOL><INDENT>util.fail(<EOL>HTTP_BAD_REQUEST, "<STR_LIT>"<EOL>)<EOL><DEDENT>if res and res.is_collection:<EOL><INDENT>self._fail(HTTP_METHOD_NOT_ALLOWED, "<STR_LIT>")<EOL><DEDENT>elif (<EOL>parentRes is None or not parentRes.is_collection<EOL>):  <EOL><INDENT>self._fail(HTTP_CONFLICT, "<STR_LIT>")<EOL><DEDENT>self._evaluate_if_headers(res, environ)<EOL>if isnewfile:<EOL><INDENT>self._check_write_permission(parentRes, "<STR_LIT:0>", environ)<EOL>res = parentRes.create_empty_resource(util.get_uri_name(path))<EOL><DEDENT>else:<EOL><INDENT>self._check_write_permission(res, "<STR_LIT:0>", environ)<EOL><DEDENT>try:<EOL><INDENT>content_length = max(-<NUM_LIT:1>, int(environ.get("<STR_LIT>", -<NUM_LIT:1>)))<EOL><DEDENT>except ValueError:<EOL><INDENT>content_length = -<NUM_LIT:1><EOL><DEDENT>if (content_length < <NUM_LIT:0>) and (<EOL>environ.get("<STR_LIT>", "<STR_LIT>").lower() != "<STR_LIT>"<EOL>):<EOL><INDENT>agent = environ.get("<STR_LIT>", "<STR_LIT>")<EOL>if "<STR_LIT>" in agent or "<STR_LIT>" in agent:  <EOL><INDENT>_logger.warning(<EOL>"<STR_LIT>"<EOL>)<EOL>content_length = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>util.fail(<EOL>HTTP_LENGTH_REQUIRED,<EOL>"<STR_LIT>".format(<EOL>environ.get("<STR_LIT>")<EOL>),<EOL>)<EOL><DEDENT><DEDENT>hasErrors = False<EOL>try:<EOL><INDENT>if environ.get("<STR_LIT>", "<STR_LIT>").lower() == "<STR_LIT>":<EOL><INDENT>data_stream = self._stream_data_chunked(environ, self.block_size)<EOL><DEDENT>else:<EOL><INDENT>data_stream = self._stream_data(<EOL>environ, content_length, self.block_size<EOL>)<EOL><DEDENT>fileobj = res.begin_write(content_type=environ.get("<STR_LIT>"))<EOL>if getattr(fileobj, "<STR_LIT>", None):<EOL><INDENT>fileobj.writelines(data_stream)<EOL><DEDENT>else:<EOL><INDENT>for data in data_stream:<EOL><INDENT>fileobj.write(data)<EOL><DEDENT><DEDENT>fileobj.close()<EOL><DEDENT>except Exception as e:<EOL><INDENT>res.end_write(with_errors=True)<EOL>_logger.exception("<STR_LIT>")<EOL>util.fail(e)<EOL><DEDENT>res.end_write(hasErrors)<EOL>headers = None<EOL>if res.support_etag():<EOL><INDENT>entitytag = res.get_etag()<EOL>if entitytag is not None:<EOL><INDENT>headers = [("<STR_LIT>", '<STR_LIT>'.format(entitytag))]<EOL><DEDENT><DEDENT>if isnewfile:<EOL><INDENT>return util.send_status_response(<EOL>environ, start_response, HTTP_CREATED, add_headers=headers<EOL>)<EOL><DEDENT>return util.send_status_response(<EOL>environ, start_response, HTTP_NO_CONTENT, add_headers=headers<EOL>)<EOL>


def _copy_or_move(self, environ, start_response, is_move):

srcPath = environ["<STR_LIT>"]<EOL>provider = self._davProvider<EOL>srcRes = provider.get_resource_inst(srcPath, environ)<EOL>srcParentRes = provider.get_resource_inst(util.get_uri_parent(srcPath), environ)<EOL>if srcRes is None:<EOL><INDENT>self._fail(HTTP_NOT_FOUND)<EOL><DEDENT>if "<STR_LIT>" not in environ:<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>if not environ.setdefault("<STR_LIT>", "<STR_LIT:T>") in ("<STR_LIT:T>", "<STR_LIT:F>"):<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>if util.get_content_length(environ) != <NUM_LIT:0>:<EOL><INDENT>body = environ["<STR_LIT>"].read(util.get_content_length(environ))<EOL>environ["<STR_LIT>"] = <NUM_LIT:1><EOL>_logger.info("<STR_LIT>".format(body[:<NUM_LIT:50>]))<EOL><DEDENT>if srcRes.is_collection:<EOL><INDENT>environ.setdefault("<STR_LIT>", "<STR_LIT>")<EOL>if not environ["<STR_LIT>"] in ("<STR_LIT:0>", "<STR_LIT>"):<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>if is_move and environ["<STR_LIT>"] != "<STR_LIT>":<EOL><INDENT>self._fail(<EOL>HTTP_BAD_REQUEST,<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>environ.setdefault("<STR_LIT>", "<STR_LIT:0>")<EOL>if not environ["<STR_LIT>"] in ("<STR_LIT:0>", "<STR_LIT>"):<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>environ["<STR_LIT>"] = "<STR_LIT:0>"<EOL><DEDENT>destinationHeader = compat.unquote(environ["<STR_LIT>"])<EOL>destScheme, destNetloc, destPath, _destParams, _destQuery, _destFrag = compat.urlparse(<EOL>destinationHeader, allow_fragments=False<EOL>)<EOL>if srcRes.is_collection:<EOL><INDENT>destPath = destPath.rstrip("<STR_LIT:/>") + "<STR_LIT:/>"<EOL><DEDENT>if destScheme and destScheme.lower() != environ["<STR_LIT>"].lower():<EOL><INDENT>self._fail(<EOL>HTTP_BAD_GATEWAY, "<STR_LIT>"<EOL>)<EOL><DEDENT>elif destNetloc and destNetloc.lower() != environ["<STR_LIT>"].lower():<EOL><INDENT>self._fail(<EOL>HTTP_BAD_GATEWAY, "<STR_LIT>"<EOL>)<EOL><DEDENT>elif not destPath.startswith(provider.mount_path + provider.share_path):<EOL><INDENT>self._fail(HTTP_BAD_GATEWAY, "<STR_LIT>")<EOL><DEDENT>destPath = destPath[len(provider.mount_path + provider.share_path) :]<EOL>assert destPath.startswith("<STR_LIT:/>")<EOL>destRes = provider.get_resource_inst(destPath, environ)<EOL>destExists = destRes is not None<EOL>destParentRes = provider.get_resource_inst(<EOL>util.get_uri_parent(destPath), environ<EOL>)<EOL>if not destParentRes or not destParentRes.is_collection:<EOL><INDENT>self._fail(HTTP_CONFLICT, "<STR_LIT>")<EOL><DEDENT>self._evaluate_if_headers(srcRes, environ)<EOL>self._evaluate_if_headers(destRes, environ)<EOL>if is_move:<EOL><INDENT>self._check_write_permission(srcRes, "<STR_LIT>", environ)<EOL>if srcParentRes:<EOL><INDENT>self._check_write_permission(srcParentRes, "<STR_LIT:0>", environ)<EOL><DEDENT><DEDENT>if not destExists:<EOL><INDENT>self._check_write_permission(destParentRes, "<STR_LIT:0>", environ)<EOL><DEDENT>self._check_write_permission(destRes, "<STR_LIT>", environ)<EOL>if srcPath == destPath:<EOL><INDENT>self._fail(HTTP_FORBIDDEN, "<STR_LIT>")<EOL><DEDENT>elif util.is_equal_or_child_uri(srcPath, destPath):<EOL><INDENT>self._fail(HTTP_FORBIDDEN, "<STR_LIT>")<EOL><DEDENT>if destExists and environ["<STR_LIT>"] != "<STR_LIT:T>":<EOL><INDENT>self._fail(<EOL>HTTP_PRECONDITION_FAILED,<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT>error_list = []<EOL>success_code = HTTP_CREATED<EOL>if destExists:<EOL><INDENT>success_code = HTTP_NO_CONTENT<EOL><DEDENT>try:<EOL><INDENT>if is_move:<EOL><INDENT>handled = srcRes.handle_move(destPath)<EOL><DEDENT>else:<EOL><INDENT>isInfinity = environ["<STR_LIT>"] == "<STR_LIT>"<EOL>handled = srcRes.handle_copy(destPath, isInfinity)<EOL><DEDENT>assert handled in (True, False) or type(handled) is list<EOL>if type(handled) is list:<EOL><INDENT>error_list = handled<EOL>handled = True<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>error_list = [(srcRes.get_href(), as_DAVError(e))]<EOL>handled = True<EOL><DEDENT>if handled:<EOL><INDENT>return self._send_response(<EOL>environ, start_response, srcRes, HTTP_NO_CONTENT, error_list<EOL>)<EOL><DEDENT>srcList = srcRes.get_descendants(add_self=True)<EOL>srcRootLen = len(srcPath)<EOL>destRootLen = len(destPath)<EOL>if destExists:<EOL><INDENT>if is_move or not destRes.is_collection or not srcRes.is_collection:<EOL><INDENT>_logger.debug("<STR_LIT>".format(destRes))<EOL>destRes.delete()<EOL>destRes = None<EOL><DEDENT>else:<EOL><INDENT>reverseDestList = destRes.get_descendants(<EOL>depth_first=True, add_self=False<EOL>)<EOL>srcPathList = [s.path for s in srcList]<EOL>_logger.debug("<STR_LIT>".format(srcPathList))<EOL>for dRes in reverseDestList:<EOL><INDENT>_logger.debug("<STR_LIT>".format(dRes))<EOL>relUrl = dRes.path[destRootLen:]<EOL>sp = srcPath + relUrl<EOL>if sp not in srcPathList:<EOL><INDENT>_logger.debug(<EOL>"<STR_LIT>".format(dRes)<EOL>)<EOL>dRes.delete()<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if is_move and srcRes.support_recursive_move(destPath):<EOL><INDENT>hasConflicts = False<EOL>for s in srcList:<EOL><INDENT>try:<EOL><INDENT>self._evaluate_if_headers(s, environ)<EOL><DEDENT>except Exception:<EOL><INDENT>hasConflicts = True<EOL>break<EOL><DEDENT><DEDENT>if not hasConflicts:<EOL><INDENT>try:<EOL><INDENT>_logger.debug("<STR_LIT>".format(srcRes, destPath))<EOL>error_list = srcRes.move_recursive(destPath)<EOL><DEDENT>except Exception as e:<EOL><INDENT>error_list = [(srcRes.get_href(), as_DAVError(e))]<EOL><DEDENT>return self._send_response(<EOL>environ, start_response, srcRes, success_code, error_list<EOL>)<EOL><DEDENT><DEDENT>ignoreDict = {}<EOL>for sRes in srcList:<EOL><INDENT>parentError = False<EOL>for ignorePath in ignoreDict.keys():<EOL><INDENT>if util.is_equal_or_child_uri(ignorePath, sRes.path):<EOL><INDENT>parentError = True<EOL>break<EOL><DEDENT><DEDENT>if parentError:<EOL><INDENT>_logger.debug(<EOL>"<STR_LIT>".format(sRes.path)<EOL>)<EOL>continue<EOL><DEDENT>try:<EOL><INDENT>relUrl = sRes.path[srcRootLen:]<EOL>dPath = destPath + relUrl<EOL>self._evaluate_if_headers(sRes, environ)<EOL>sRes.copy_move_single(dPath, is_move)<EOL>if is_move and not sRes.is_collection:<EOL><INDENT>sRes.delete()<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>ignoreDict[sRes.path] = True<EOL>error_list.append((sRes.get_href(), as_DAVError(e)))<EOL><DEDENT><DEDENT>if is_move:<EOL><INDENT>reverseSrcList = srcList[:]<EOL>reverseSrcList.reverse()<EOL>_logger.debug("<STR_LIT>".format(ignoreDict))<EOL>for sRes in reverseSrcList:<EOL><INDENT>if not sRes.is_collection:<EOL><INDENT>continue<EOL><DEDENT>childError = False<EOL>for ignorePath in ignoreDict.keys():<EOL><INDENT>if util.is_equal_or_child_uri(sRes.path, ignorePath):<EOL><INDENT>childError = True<EOL>break<EOL><DEDENT><DEDENT>if childError:<EOL><INDENT>_logger.debug(<EOL>"<STR_LIT>".format(<EOL>sRes.path<EOL>)<EOL>)<EOL>continue<EOL><DEDENT>try:<EOL><INDENT>_logger.debug("<STR_LIT>".format(sRes))<EOL>sRes.delete()<EOL><DEDENT>except Exception as e:<EOL><INDENT>error_list.append((srcRes.get_href(), as_DAVError(e)))<EOL><DEDENT><DEDENT>_logger.debug("<STR_LIT>".format(error_list))<EOL><DEDENT>return self._send_response(<EOL>environ, start_response, srcRes, success_code, error_list<EOL>)<EOL>

@see: http://www.webdav.org/specs/rfc4918.html#METHOD_COPY
@see: http://www.webdav.org/specs/rfc4918.html#METHOD_MOVE


def do_LOCK(self, environ, start_response):

path = environ["<STR_LIT>"]<EOL>provider = self._davProvider<EOL>res = provider.get_resource_inst(path, environ)<EOL>lockMan = provider.lock_manager<EOL>if lockMan is None:<EOL><INDENT>self._fail(HTTP_NOT_IMPLEMENTED, "<STR_LIT>")<EOL><DEDENT>if res and res.prevent_locking():<EOL><INDENT>self._fail(HTTP_FORBIDDEN, "<STR_LIT>")<EOL><DEDENT>if environ.setdefault("<STR_LIT>", "<STR_LIT>") not in ("<STR_LIT:0>", "<STR_LIT>"):<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>self._evaluate_if_headers(res, environ)<EOL>timeoutsecs = util.read_timeout_value_header(environ.get("<STR_LIT>", "<STR_LIT>"))<EOL>submittedTokenList = environ["<STR_LIT>"]<EOL>lockinfoEL = util.parse_xml_body(environ, allow_empty=True)<EOL>if lockinfoEL is None:<EOL><INDENT>environ["<STR_LIT>"] = "<STR_LIT:0>"  <EOL>if res is None:<EOL><INDENT>self._fail(<EOL>HTTP_BAD_REQUEST, "<STR_LIT>"<EOL>)<EOL><DEDENT>if len(submittedTokenList) != <NUM_LIT:1>:<EOL><INDENT>self._fail(<EOL>HTTP_BAD_REQUEST,<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT>elif not lockMan.is_url_locked_by_token(<EOL>res.get_ref_url(), submittedTokenList[<NUM_LIT:0>]<EOL>):<EOL><INDENT>self._fail(<EOL>HTTP_PRECONDITION_FAILED,<EOL>"<STR_LIT>",<EOL>err_condition=PRECONDITION_CODE_LockTokenMismatch,<EOL>)<EOL><DEDENT>lock = lockMan.refresh(submittedTokenList[<NUM_LIT:0>], timeoutsecs)<EOL>lockPath = provider.ref_url_to_path(lock["<STR_LIT:root>"])<EOL>lockRes = provider.get_resource_inst(lockPath, environ)<EOL>propEL = xml_tools.make_prop_el()<EOL>lockdiscoveryEL = lockRes.get_property_value("<STR_LIT>")<EOL>propEL.append(lockdiscoveryEL)<EOL>xml = xml_tools.xml_to_bytes(propEL)<EOL>start_response(<EOL>"<STR_LIT>",<EOL>[<EOL>("<STR_LIT:Content-Type>", "<STR_LIT>"),<EOL>("<STR_LIT>", str(len(xml))),<EOL>("<STR_LIT>", util.get_rfc1123_time()),<EOL>],<EOL>)<EOL>return [xml]<EOL><DEDENT>if lockinfoEL.tag != "<STR_LIT>":<EOL><INDENT>self._fail(HTTP_BAD_REQUEST)<EOL><DEDENT>lock_type = None<EOL>lock_scope = None<EOL>lock_owner = compat.to_bytes("<STR_LIT>")<EOL>lock_depth = environ.setdefault("<STR_LIT>", "<STR_LIT>")<EOL>for linode in lockinfoEL:<EOL><INDENT>if linode.tag == "<STR_LIT>":<EOL><INDENT>for lsnode in linode:<EOL><INDENT>if lsnode.tag == "<STR_LIT>":<EOL><INDENT>lock_scope = "<STR_LIT>"<EOL><DEDENT>elif lsnode.tag == "<STR_LIT>":<EOL><INDENT>lock_scope = "<STR_LIT>"<EOL><DEDENT>break<EOL><DEDENT><DEDENT>elif linode.tag == "<STR_LIT>":<EOL><INDENT>for ltnode in linode:<EOL><INDENT>if ltnode.tag == "<STR_LIT>":<EOL><INDENT>lock_type = "<STR_LIT>"  <EOL><DEDENT>break<EOL><DEDENT><DEDENT>elif linode.tag == "<STR_LIT>":<EOL><INDENT>lock_owner = xml_tools.xml_to_bytes(linode, pretty_print=False)<EOL><DEDENT>else:<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>".format(linode.tag))<EOL><DEDENT><DEDENT>if not lock_scope:<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>if not lock_type:<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>if environ.get("<STR_LIT>"):<EOL><INDENT>pass  <EOL><DEDENT>createdNewResource = False<EOL>if res is None:<EOL><INDENT>parentRes = provider.get_resource_inst(util.get_uri_parent(path), environ)<EOL>if not parentRes or not parentRes.is_collection:<EOL><INDENT>self._fail(HTTP_CONFLICT, "<STR_LIT>")<EOL><DEDENT>res = parentRes.create_empty_resource(util.get_uri_name(path))<EOL>createdNewResource = True<EOL><DEDENT>lock = lockMan.acquire(<EOL>res.get_ref_url(),<EOL>lock_type,<EOL>lock_scope,<EOL>lock_depth,<EOL>lock_owner,<EOL>timeoutsecs,<EOL>environ["<STR_LIT>"],<EOL>submittedTokenList,<EOL>)<EOL>propEL = xml_tools.make_prop_el()<EOL>lockdiscoveryEL = res.get_property_value("<STR_LIT>")<EOL>propEL.append(lockdiscoveryEL)<EOL>respcode = "<STR_LIT>"<EOL>if createdNewResource:<EOL><INDENT>respcode = "<STR_LIT>"<EOL><DEDENT>xml = xml_tools.xml_to_bytes(propEL)<EOL>start_response(<EOL>respcode,<EOL>[<EOL>("<STR_LIT:Content-Type>", "<STR_LIT>"),<EOL>("<STR_LIT>", str(len(xml))),<EOL>("<STR_LIT>", lock["<STR_LIT>"]),<EOL>("<STR_LIT>", util.get_rfc1123_time()),<EOL>],<EOL>)<EOL>return [xml]<EOL>


def do_UNLOCK(self, environ, start_response):

path = environ["<STR_LIT>"]<EOL>provider = self._davProvider<EOL>res = self._davProvider.get_resource_inst(path, environ)<EOL>lockMan = provider.lock_manager<EOL>if lockMan is None:<EOL><INDENT>self._fail(HTTP_NOT_IMPLEMENTED, "<STR_LIT>")<EOL><DEDENT>elif util.get_content_length(environ) != <NUM_LIT:0>:<EOL><INDENT>self._fail(<EOL>HTTP_MEDIATYPE_NOT_SUPPORTED,<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT>elif res is None:<EOL><INDENT>self._fail(HTTP_NOT_FOUND)<EOL><DEDENT>elif "<STR_LIT>" not in environ:<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>self._evaluate_if_headers(res, environ)<EOL>lockToken = environ["<STR_LIT>"].strip("<STR_LIT>")<EOL>refUrl = res.get_ref_url()<EOL>if not lockMan.is_url_locked_by_token(refUrl, lockToken):<EOL><INDENT>self._fail(<EOL>HTTP_CONFLICT,<EOL>"<STR_LIT>",<EOL>err_condition=PRECONDITION_CODE_LockTokenMismatch,<EOL>)<EOL><DEDENT>if not lockMan.is_token_locked_by_user(lockToken, environ["<STR_LIT>"]):<EOL><INDENT>self._fail(HTTP_FORBIDDEN, "<STR_LIT>")<EOL><DEDENT>lockMan.release(lockToken)<EOL>return util.send_status_response(environ, start_response, HTTP_NO_CONTENT)<EOL>


def do_OPTIONS(self, environ, start_response):

path = environ["<STR_LIT>"]<EOL>provider = self._davProvider<EOL>res = provider.get_resource_inst(path, environ)<EOL>dav_compliance_level = "<STR_LIT>"<EOL>if provider is None or provider.is_readonly() or provider.lock_manager is None:<EOL><INDENT>dav_compliance_level = "<STR_LIT:1>"<EOL><DEDENT>headers = [<EOL>("<STR_LIT:Content-Type>", "<STR_LIT>"),<EOL>("<STR_LIT>", "<STR_LIT:0>"),<EOL>("<STR_LIT>", dav_compliance_level),<EOL>("<STR_LIT>", util.get_rfc1123_time()),<EOL>]<EOL>if path == "<STR_LIT:/>":<EOL><INDENT>path = "<STR_LIT:*>"  <EOL><DEDENT>if path == "<STR_LIT:*>":<EOL><INDENT>start_response("<STR_LIT>", headers)<EOL>return [b"<STR_LIT>"]<EOL><DEDENT>allow = ["<STR_LIT>"]<EOL>if res and res.is_collection:<EOL><INDENT>allow.extend(["<STR_LIT>", "<STR_LIT:GET>", "<STR_LIT>"])<EOL>if not provider.is_readonly():<EOL><INDENT>allow.extend(["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>"])<EOL>if provider.lock_manager is not None:<EOL><INDENT>allow.extend(["<STR_LIT>", "<STR_LIT>"])<EOL><DEDENT><DEDENT><DEDENT>elif res:<EOL><INDENT>allow.extend(["<STR_LIT>", "<STR_LIT:GET>", "<STR_LIT>"])<EOL>if not provider.is_readonly():<EOL><INDENT>allow.extend(["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>"])<EOL>if provider.lock_manager is not None:<EOL><INDENT>allow.extend(["<STR_LIT>", "<STR_LIT>"])<EOL><DEDENT><DEDENT>if res.support_ranges():<EOL><INDENT>headers.append(("<STR_LIT>", "<STR_LIT>"))<EOL><DEDENT><DEDENT>elif provider.is_collection(util.get_uri_parent(path), environ):<EOL><INDENT>if not provider.is_readonly():<EOL><INDENT>allow.extend(["<STR_LIT>", "<STR_LIT>"])<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self._fail(HTTP_NOT_FOUND)<EOL><DEDENT>headers.append(("<STR_LIT>", "<STR_LIT:U+0020>".join(allow)))<EOL>if environ["<STR_LIT>"].get("<STR_LIT>", False):<EOL><INDENT>headers.append(("<STR_LIT>", "<STR_LIT>"))<EOL><DEDENT>start_response("<STR_LIT>", headers)<EOL>return [b"<STR_LIT>"]<EOL>


def _send_resource(self, environ, start_response, is_head_method):

path = environ["<STR_LIT>"]<EOL>res = self._davProvider.get_resource_inst(path, environ)<EOL>if util.get_content_length(environ) != <NUM_LIT:0>:<EOL><INDENT>self._fail(<EOL>HTTP_MEDIATYPE_NOT_SUPPORTED,<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT>elif environ.setdefault("<STR_LIT>", "<STR_LIT:0>") != "<STR_LIT:0>":<EOL><INDENT>self._fail(HTTP_BAD_REQUEST, "<STR_LIT>")<EOL><DEDENT>elif res is None:<EOL><INDENT>self._fail(HTTP_NOT_FOUND)<EOL><DEDENT>elif res.is_collection:<EOL><INDENT>self._fail(<EOL>HTTP_FORBIDDEN,<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>",<EOL>)<EOL><DEDENT>self._evaluate_if_headers(res, environ)<EOL>filesize = res.get_content_length()<EOL>if filesize is None:<EOL><INDENT>filesize = -<NUM_LIT:1>  <EOL><DEDENT>last_modified = res.get_last_modified()<EOL>if last_modified is None:<EOL><INDENT>last_modified = -<NUM_LIT:1><EOL><DEDENT>entitytag = res.get_etag()<EOL>if entitytag is None:<EOL><INDENT>entitytag = "<STR_LIT>"<EOL><DEDENT>doignoreranges = (<EOL>not res.support_content_length()<EOL>or not res.support_ranges()<EOL>or filesize == <NUM_LIT:0><EOL>)<EOL>if (<EOL>"<STR_LIT>" in environ<EOL>and "<STR_LIT>" in environ<EOL>and not doignoreranges<EOL>):<EOL><INDENT>ifrange = environ["<STR_LIT>"]<EOL>secstime = util.parse_time_string(ifrange)<EOL>if secstime:<EOL><INDENT>if last_modified != secstime:<EOL><INDENT>doignoreranges = True<EOL><DEDENT><DEDENT>else:<EOL><INDENT>ifrange = ifrange.strip('<STR_LIT>')<EOL>if entitytag is None or ifrange != entitytag:<EOL><INDENT>doignoreranges = True<EOL><DEDENT><DEDENT><DEDENT>ispartialranges = False<EOL>if "<STR_LIT>" in environ and not doignoreranges:<EOL><INDENT>ispartialranges = True<EOL>list_ranges, _totallength = util.obtain_content_ranges(<EOL>environ["<STR_LIT>"], filesize<EOL>)<EOL>if len(list_ranges) == <NUM_LIT:0>:<EOL><INDENT>self._fail(HTTP_RANGE_NOT_SATISFIABLE)<EOL><DEDENT>(range_start, range_end, range_length) = list_ranges[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>(range_start, range_end, range_length) = (<NUM_LIT:0>, filesize - <NUM_LIT:1>, filesize)<EOL><DEDENT>mimetype = res.get_content_type()  <EOL>response_headers = []<EOL>if res.support_content_length():<EOL><INDENT>response_headers.append(("<STR_LIT>", str(range_length)))<EOL><DEDENT>if res.support_modified():<EOL><INDENT>response_headers.append(<EOL>("<STR_LIT>", util.get_rfc1123_time(last_modified))<EOL>)<EOL><DEDENT>response_headers.append(("<STR_LIT:Content-Type>", mimetype))<EOL>response_headers.append(("<STR_LIT>", util.get_rfc1123_time()))<EOL>if res.support_etag():<EOL><INDENT>response_headers.append(("<STR_LIT>", '<STR_LIT>'.format(entitytag)))<EOL><DEDENT>if "<STR_LIT>" in environ["<STR_LIT>"]:<EOL><INDENT>customHeaders = environ["<STR_LIT>"]["<STR_LIT>"]<EOL>for header, value in customHeaders:<EOL><INDENT>response_headers.append((header, value))<EOL><DEDENT><DEDENT>res.finalize_headers(environ, response_headers)<EOL>if ispartialranges:<EOL><INDENT>response_headers.append(<EOL>(<EOL>"<STR_LIT>",<EOL>"<STR_LIT>".format(range_start, range_end, filesize),<EOL>)<EOL>)<EOL>start_response("<STR_LIT>", response_headers)<EOL><DEDENT>else:<EOL><INDENT>start_response("<STR_LIT>", response_headers)<EOL><DEDENT>if is_head_method:<EOL><INDENT>yield b"<STR_LIT>"<EOL>return<EOL><DEDENT>fileobj = res.get_content()<EOL>if not doignoreranges:<EOL><INDENT>fileobj.seek(range_start)<EOL><DEDENT>contentlengthremaining = range_length<EOL>while <NUM_LIT:1>:<EOL><INDENT>if contentlengthremaining < <NUM_LIT:0> or contentlengthremaining > self.block_size:<EOL><INDENT>readbuffer = fileobj.read(self.block_size)<EOL><DEDENT>else:<EOL><INDENT>readbuffer = fileobj.read(contentlengthremaining)<EOL><DEDENT>assert compat.is_bytes(readbuffer)<EOL>yield readbuffer<EOL>contentlengthremaining -= len(readbuffer)<EOL>if len(readbuffer) == <NUM_LIT:0> or contentlengthremaining == <NUM_LIT:0>:<EOL><INDENT>break<EOL><DEDENT><DEDENT>fileobj.close()<EOL>return<EOL>

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


if self.is_collection:<EOL><INDENT>return None<EOL><DEDENT>raise NotImplementedError<EOL>

Contains the Content-Length header returned by a GET without accept
        headers.

        The getcontentlength property MUST be defined on any DAV compliant
        resource that returns the Content-Length header in response to a GET.

        This method MUST be implemented by non-collections only.


Contains the Content-Type header returned by a GET without accept
        headers.

        This getcontenttype property MUST be defined on any DAV compliant
        resource that returns the Content-Type header in response to a GET.
        See http://www.webdav.org/specs/rfc4918.html#PROPERTY_getcontenttype

        This method MUST be implemented by non-collections only.


return None<EOL>

Records the time and date the resource was created.

        The creationdate property should be defined on all DAV compliant
        resources. If present, it contains a timestamp of the moment when the
        resource was created (i.e., the moment it had non-null state).

        This method SHOULD be implemented, especially by non-collections.


assert self.is_collection<EOL>return None<EOL>

Return a list of dictionaries with information for directory
        rendering.

        This default implementation return None, so the dir browser will
        traverse all members.

        This method COULD be implemented for collection resources.


return self.name<EOL>

Provides a name for the resource that is suitable for presentation to
        a user.

        The displayname property should be defined on all DAV compliant
        resources. If present, the property contains a description of the
        resource that is suitable for presentation to a user.

        This default implementation returns `name`, which is the last path
        segment.


if self.is_collection:<EOL><INDENT>return {"<STR_LIT:type>": "<STR_LIT>"}<EOL><DEDENT>elif os.extsep in self.name:<EOL><INDENT>ext = self.name.split(os.extsep)[-<NUM_LIT:1>].upper()<EOL>if len(ext) < <NUM_LIT:5>:<EOL><INDENT>return {"<STR_LIT:type>": "<STR_LIT>".format(ext)}<EOL><DEDENT><DEDENT>return {"<STR_LIT:type>": "<STR_LIT>"}<EOL>

Return additional info dictionary for displaying (optional).

        This information is not part of the DAV specification, but meant for use
        by the dir browser middleware.

        This default implementation returns ``{'type': '...'}``


return None<EOL>

See http://www.webdav.org/specs/rfc4918.html#PROPERTY_getetag

This method SHOULD be implemented, especially by non-collections.


return None<EOL>

Contains the Last-Modified header returned by a GET method without
        accept headers.

        Return None, if this live property is not supported.

        Note that the last-modified date on a resource may reflect changes in
        any part of the state of the resource, not necessarily just a change to
        the response to the GET method. For example, a change in a property may
        cause the last-modified date to change. The getlastmodified property
        MUST be defined on any DAV compliant resource that returns the
        Last-Modified header in response to a GET.

        This method SHOULD be implemented, especially by non-collections.


def set_last_modified(self, dest_path, time_stamp, dry_run):

raise NotImplementedError<EOL>

Set last modified time for destPath to timeStamp on epoch-format


raise NotImplementedError<EOL>

Return True, if this non-resource supports Range on GET requests.

        This method MUST be implemented by non-collections only.


return self.get_content_length() is not None<EOL>

Return True, if this resource supports Content-Length.

        This default implementation checks `self.get_content_length() is None`.


return self.get_etag() is not None<EOL>

Return True, if this resource supports ETags.

        This default implementation checks `self.get_etag() is None`.


return self.get_last_modified() is not None<EOL>

Return True, if this resource supports last modified dates.

        This default implementation checks `self.get_last_modified() is None`.


if self.path in ("<STR_LIT>", "<STR_LIT:/>"):<EOL><INDENT>return "<STR_LIT:/>"<EOL><DEDENT>if self.is_collection and not self.path.endswith("<STR_LIT:/>"):<EOL><INDENT>return self.path + "<STR_LIT:/>"<EOL><DEDENT>return self.path<EOL>

Return preferred mapping for a resource mapping.

        Different URLs may map to the same resource, e.g.:
            '/a/b' == '/A/b' == '/a/b/'
        get_preferred_path() returns the same value for all these variants, e.g.:
            '/a/b/'   (assuming resource names considered case insensitive)

        @param path: a UTF-8 encoded, unquoted byte string.
        @return: a UTF-8 encoded, unquoted byte string.


return compat.quote(self.provider.share_path + self.get_preferred_path())<EOL>

Return the quoted, absolute, unique URL of a resource, relative to appRoot.

        Byte string, UTF-8 encoded, quoted.
        Starts with a '/'. Collections also have a trailing '/'.

        This is basically the same as get_preferred_path, but deals with
        'virtual locations' as well.

        e.g. '/a/b' == '/A/b' == '/bykey/123' == '/byguid/abc532'

        get_ref_url() returns the same value for all these URLs, so it can be
        used as a key for locking and persistence storage.

        DAV providers that allow virtual-mappings must override this method.

        See also comments in DEVELOPERS.txt glossary.


<EOL>safe = "<STR_LIT:/>" + "<STR_LIT>" + "<STR_LIT>"<EOL>return compat.quote(<EOL>self.provider.mount_path<EOL>+ self.provider.share_path<EOL>+ self.get_preferred_path(),<EOL>safe=safe,<EOL>)<EOL>

Convert path to a URL that can be passed to XML responses.

        Byte string, UTF-8 encoded, quoted.

        See http://www.webdav.org/specs/rfc4918.html#rfc.section.8.3
        We are using the path-absolute option. i.e. starting with '/'.
        URI ; See section 3.2.1 of [RFC2068]


if not self.is_collection:<EOL><INDENT>raise NotImplementedError<EOL><DEDENT>memberList = []<EOL>for name in self.get_member_names():<EOL><INDENT>member = self.get_member(name)<EOL>assert member is not None<EOL>memberList.append(member)<EOL><DEDENT>return memberList<EOL>

Return a list of direct members (_DAVResource or derived objects).

        This default implementation calls self.get_member_names() and
        self.get_member() for each of them.
        A provider COULD overwrite this for performance reasons.


raise NotImplementedError<EOL>

Return list of (direct) collection member names (UTF-8 byte strings).

        Every provider MUST provide this method for collection resources.


assert depth in ("<STR_LIT:0>", "<STR_LIT:1>", "<STR_LIT>")<EOL>res = []<EOL>if add_self and not depth_first:<EOL><INDENT>res.append(self)<EOL><DEDENT>if depth != "<STR_LIT:0>" and self.is_collection:<EOL><INDENT>for child in self.get_member_list():<EOL><INDENT>if not child:<EOL><INDENT>self.get_member_list()<EOL><DEDENT>want = (collections and child.is_collection) or (<EOL>resources and not child.is_collection<EOL>)<EOL>if want and not depth_first:<EOL><INDENT>res.append(child)<EOL><DEDENT>if child.is_collection and depth == "<STR_LIT>":<EOL><INDENT>res.extend(<EOL>child.get_descendants(<EOL>collections, resources, depth_first, depth, add_self=False<EOL>)<EOL>)<EOL><DEDENT>if want and depth_first:<EOL><INDENT>res.append(child)<EOL><DEDENT><DEDENT><DEDENT>if add_self and depth_first:<EOL><INDENT>res.append(self)<EOL><DEDENT>return res<EOL>

Return a list _DAVResource objects of a collection (children,
        grand-children, ...).

        This default implementation calls self.get_member_list() recursively.

        This function may also be called for non-collections (with add_self=True).

        :Parameters:
            depth_first : bool
                use <False>, to list containers before content.
                (e.g. when moving / copying branches.)
                Use <True>, to list content before containers.
                (e.g. when deleting branches.)
            depth : string
                '0' | '1' | 'infinity'


<EOL>propNameList = []<EOL>propNameList.append("<STR_LIT>")<EOL>if self.get_creation_date() is not None:<EOL><INDENT>propNameList.append("<STR_LIT>")<EOL><DEDENT>if self.get_content_length() is not None:<EOL><INDENT>assert not self.is_collection<EOL>propNameList.append("<STR_LIT>")<EOL><DEDENT>if self.get_content_type() is not None:<EOL><INDENT>propNameList.append("<STR_LIT>")<EOL><DEDENT>if self.get_last_modified() is not None:<EOL><INDENT>propNameList.append("<STR_LIT>")<EOL><DEDENT>if self.get_display_name() is not None:<EOL><INDENT>propNameList.append("<STR_LIT>")<EOL><DEDENT>if self.get_etag() is not None:<EOL><INDENT>propNameList.append("<STR_LIT>")<EOL><DEDENT>if self.provider.lock_manager and not self.prevent_locking():<EOL><INDENT>propNameList.extend(_lockPropertyNames)<EOL><DEDENT>if self.provider.prop_manager:<EOL><INDENT>refUrl = self.get_ref_url()<EOL>propNameList.extend(<EOL>self.provider.prop_manager.get_properties(refUrl, self.environ)<EOL>)<EOL><DEDENT>return propNameList<EOL>

Return list of supported property names in Clark Notation.

        Note that 'allprop', despite its name, which remains for
        backward-compatibility, does not return every property, but only dead
        properties and the live properties defined in RFC4918.

        This default implementation returns a combination of:

        - Supported standard live properties in the {DAV:} namespace, if the
          related getter method returns not None.
        - {DAV:}lockdiscovery and {DAV:}supportedlock, if a lock manager is
          present
        - If a property manager is present, then a list of dead properties is
          appended

        A resource provider may override this method, to add a list of
        supported custom live property names.


def get_properties(self, mode, name_list=None):

assert mode in ("<STR_LIT>", "<STR_LIT:name>", "<STR_LIT>")<EOL>if mode in ("<STR_LIT>", "<STR_LIT:name>"):<EOL><INDENT>assert name_list is None<EOL>name_list = self.get_property_names(mode == "<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>assert name_list is not None<EOL><DEDENT>propList = []<EOL>namesOnly = mode == "<STR_LIT:name>"<EOL>for name in name_list:<EOL><INDENT>try:<EOL><INDENT>if namesOnly:<EOL><INDENT>propList.append((name, None))<EOL><DEDENT>else:<EOL><INDENT>value = self.get_property_value(name)<EOL>propList.append((name, value))<EOL><DEDENT><DEDENT>except DAVError as e:<EOL><INDENT>propList.append((name, e))<EOL><DEDENT>except Exception as e:<EOL><INDENT>propList.append((name, as_DAVError(e)))<EOL>if self.provider.verbose >= <NUM_LIT:2>:<EOL><INDENT>traceback.print_exc(<NUM_LIT:10>, sys.stdout)<EOL><DEDENT><DEDENT><DEDENT>return propList<EOL>

Return properties as list of 2-tuples (name, value).

        If mode is 'name', then None is returned for the value.

        name
            the property name in Clark notation.
        value
            may have different types, depending on the status:
            - string or unicode: for standard property values.
            - etree.Element: for complex values.
            - DAVError in case of errors.
            - None: if mode == 'name'.

        @param mode: "allprop", "name", or "named"
        @param name_list: list of property names in Clark Notation (required for mode 'named')

        This default implementation basically calls self.get_property_names() to
        get the list of names, then call self.get_property_value on each of them.


refUrl = self.get_ref_url()<EOL>lm = self.provider.lock_manager<EOL>if lm and name == "<STR_LIT>":<EOL><INDENT>activelocklist = lm.get_url_lock_list(refUrl)<EOL>lockdiscoveryEL = etree.Element(name)<EOL>for lock in activelocklist:<EOL><INDENT>activelockEL = etree.SubElement(lockdiscoveryEL, "<STR_LIT>")<EOL>locktypeEL = etree.SubElement(activelockEL, "<STR_LIT>")<EOL>etree.SubElement(locktypeEL, "<STR_LIT>".format("<STR_LIT>", lock["<STR_LIT:type>"]))<EOL>lockscopeEL = etree.SubElement(activelockEL, "<STR_LIT>")<EOL>etree.SubElement(lockscopeEL, "<STR_LIT>".format("<STR_LIT>", lock["<STR_LIT>"]))<EOL>etree.SubElement(activelockEL, "<STR_LIT>").text = lock["<STR_LIT>"]<EOL>if lock["<STR_LIT>"]:<EOL><INDENT>ownerEL = xml_tools.string_to_xml(lock["<STR_LIT>"])<EOL>activelockEL.append(ownerEL)<EOL><DEDENT>timeout = lock["<STR_LIT>"]<EOL>if timeout < <NUM_LIT:0>:<EOL><INDENT>timeout = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>expire = lock["<STR_LIT>"]<EOL>timeout = "<STR_LIT>" + str(int(expire - time.time()))<EOL><DEDENT>etree.SubElement(activelockEL, "<STR_LIT>").text = timeout<EOL>locktokenEL = etree.SubElement(activelockEL, "<STR_LIT>")<EOL>etree.SubElement(locktokenEL, "<STR_LIT>").text = lock["<STR_LIT>"]<EOL>lockPath = self.provider.ref_url_to_path(lock["<STR_LIT:root>"])<EOL>lockRes = self.provider.get_resource_inst(lockPath, self.environ)<EOL>lockHref = lockRes.get_href()<EOL>lockrootEL = etree.SubElement(activelockEL, "<STR_LIT>")<EOL>etree.SubElement(lockrootEL, "<STR_LIT>").text = lockHref<EOL><DEDENT>return lockdiscoveryEL<EOL><DEDENT>elif lm and name == "<STR_LIT>":<EOL><INDENT>supportedlockEL = etree.Element(name)<EOL>lockentryEL = etree.SubElement(supportedlockEL, "<STR_LIT>")<EOL>lockscopeEL = etree.SubElement(lockentryEL, "<STR_LIT>")<EOL>etree.SubElement(lockscopeEL, "<STR_LIT>")<EOL>locktypeEL = etree.SubElement(lockentryEL, "<STR_LIT>")<EOL>etree.SubElement(locktypeEL, "<STR_LIT>")<EOL>lockentryEL = etree.SubElement(supportedlockEL, "<STR_LIT>")<EOL>lockscopeEL = etree.SubElement(lockentryEL, "<STR_LIT>")<EOL>etree.SubElement(lockscopeEL, "<STR_LIT>")<EOL>locktypeEL = etree.SubElement(lockentryEL, "<STR_LIT>")<EOL>etree.SubElement(locktypeEL, "<STR_LIT>")<EOL>return supportedlockEL<EOL><DEDENT>elif name.startswith("<STR_LIT>"):<EOL><INDENT>if name == "<STR_LIT>" and self.get_creation_date() is not None:<EOL><INDENT>return util.get_rfc3339_time(self.get_creation_date())<EOL><DEDENT>elif name == "<STR_LIT>" and self.get_content_type() is not None:<EOL><INDENT>return self.get_content_type()<EOL><DEDENT>elif name == "<STR_LIT>":<EOL><INDENT>if self.is_collection:<EOL><INDENT>resourcetypeEL = etree.Element(name)<EOL>etree.SubElement(resourcetypeEL, "<STR_LIT>")<EOL>return resourcetypeEL<EOL><DEDENT>return "<STR_LIT>"<EOL><DEDENT>elif (<EOL>name == "<STR_LIT>" and self.get_last_modified() is not None<EOL>):<EOL><INDENT>return util.get_rfc1123_time(self.get_last_modified())<EOL><DEDENT>elif (<EOL>name == "<STR_LIT>"<EOL>and self.get_content_length() is not None<EOL>):<EOL><INDENT>return str(self.get_content_length())<EOL><DEDENT>elif name == "<STR_LIT>" and self.get_etag() is not None:<EOL><INDENT>return self.get_etag()<EOL><DEDENT>elif name == "<STR_LIT>" and self.get_display_name() is not None:<EOL><INDENT>return self.get_display_name()<EOL><DEDENT>raise DAVError(HTTP_NOT_FOUND)<EOL><DEDENT>pm = self.provider.prop_manager<EOL>if pm:<EOL><INDENT>value = pm.get_property(refUrl, name, self.environ)<EOL>if value is not None:<EOL><INDENT>return xml_tools.string_to_xml(value)<EOL><DEDENT><DEDENT>raise DAVError(HTTP_NOT_FOUND)<EOL>

Return the value of a property.

        name:
            the property name in Clark notation.
        return value:
            may have different types, depending on the status:

            - string or unicode: for standard property values.
            - lxml.etree.Element: for complex values.

            If the property is not available, a DAVError is raised.

        This default implementation handles ``{DAV:}lockdiscovery`` and
        ``{DAV:}supportedlock`` using the associated lock manager.

        All other *live* properties (i.e. name starts with ``{DAV:}``) are
        delegated to the self.xxx() getters.

        Finally, other properties are considered *dead*, and are handled  by
        the associated property manager.


def set_property_value(self, name, value, dry_run=False):

assert value is None or xml_tools.is_etree_element(value)<EOL>if name in _lockPropertyNames:<EOL><INDENT>raise DAVError(<EOL>HTTP_FORBIDDEN, err_condition=PRECONDITION_CODE_ProtectedProperty<EOL>)<EOL><DEDENT>config = self.environ["<STR_LIT>"]<EOL>mutableLiveProps = config.get("<STR_LIT>", [])<EOL>if (<EOL>name.startswith("<STR_LIT>")<EOL>and name in _standardLivePropNames<EOL>and name in mutableLiveProps<EOL>):<EOL><INDENT>if name in ("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>try:<EOL><INDENT>return self.set_last_modified(self.path, value.text, dry_run)<EOL><DEDENT>except Exception:<EOL><INDENT>_logger.warning(<EOL>"<STR_LIT>".format(<EOL>self.path<EOL>)<EOL>)<EOL><DEDENT><DEDENT>raise DAVError(HTTP_FORBIDDEN)<EOL><DEDENT>if name.startswith("<STR_LIT>"):<EOL><INDENT>agent = self.environ.get("<STR_LIT>", "<STR_LIT:None>")<EOL>win32_emu = config.get("<STR_LIT>", {}).get("<STR_LIT>", False)<EOL>if win32_emu and "<STR_LIT>" not in agent:<EOL><INDENT>if "<STR_LIT>" in name:<EOL><INDENT>return self.set_last_modified(self.path, value.text, dry_run)<EOL><DEDENT>elif "<STR_LIT>" in name:<EOL><INDENT>return True<EOL><DEDENT>elif "<STR_LIT>" in name:<EOL><INDENT>return True<EOL><DEDENT>elif "<STR_LIT>" in name:<EOL><INDENT>return True<EOL><DEDENT><DEDENT><DEDENT>pm = self.provider.prop_manager<EOL>if pm and not name.startswith("<STR_LIT>"):<EOL><INDENT>refUrl = self.get_ref_url()<EOL>if value is None:<EOL><INDENT>return pm.remove_property(refUrl, name, dry_run, self.environ)<EOL><DEDENT>else:<EOL><INDENT>value = etree.tostring(value)<EOL>return pm.write_property(refUrl, name, value, dry_run, self.environ)<EOL><DEDENT><DEDENT>raise DAVError(HTTP_FORBIDDEN)<EOL>

Set a property value or remove a property.

        value == None means 'remove property'.
        Raise HTTP_FORBIDDEN if property is read-only, or not supported.

        When dry_run is True, this function should raise errors, as in a real
        run, but MUST NOT change any data.

        This default implementation

        - raises HTTP_FORBIDDEN, if trying to modify a locking property
        - raises HTTP_FORBIDDEN, if trying to modify an immutable {DAV:}
          property
        - handles Windows' Win32LastModifiedTime to set the getlastmodified
          property, if enabled
        - stores everything else as dead property, if a property manager is
          present.
        - raises HTTP_FORBIDDEN, else

        Removing a non-existing prop is NOT an error.

        Note: RFC 4918 states that {DAV:}displayname 'SHOULD NOT be protected'

        A resource provider may override this method, to update supported custom
        live properties.


if self.provider.prop_manager:<EOL><INDENT>self.provider.prop_manager.remove_properties(<EOL>self.get_ref_url(), self.environ<EOL>)<EOL><DEDENT>


return False<EOL>

Return True, to prevent locking.

        This default implementation returns ``False``, so standard processing
        takes place: locking (and refreshing of locks) is implemented using
        the lock manager, if one is configured.


if self.provider.lock_manager is None:<EOL><INDENT>return False<EOL><DEDENT>return self.provider.lock_manager.is_url_locked(self.get_ref_url())<EOL>


assert self.is_collection<EOL>raise DAVError(HTTP_FORBIDDEN)<EOL>

Create and return an empty (length-0) resource as member of self.

        Called for LOCK requests on unmapped URLs.

        Preconditions (to be ensured by caller):

          - this must be a collection
          - <self.path + name> must not exist
          - there must be no conflicting locks

        Returns a DAVResuource.

        This method MUST be implemented by all providers that support write
        access.
        This default implementation simply raises HTTP_FORBIDDEN.


Create a new collection as member of self.

        Preconditions (to be ensured by caller):

          - this must be a collection
          - <self.path + name> must not exist
          - there must be no conflicting locks

        This method MUST be implemented by all providers that support write
        access.
        This default implementation raises HTTP_FORBIDDEN.


assert not self.is_collection<EOL>raise NotImplementedError<EOL>

Open content as a stream for reading.

        Returns a file-like object / stream containing the contents of the
        resource specified.
        The calling application will close() the stream.

        This method MUST be implemented by all providers.


assert not self.is_collection<EOL>raise DAVError(HTTP_FORBIDDEN)<EOL>

Open content as a stream for writing.

        This method MUST be implemented by all providers that support write
        access.


pass<EOL>

Called when PUT has finished writing.

        This is only a notification. that MAY be handled.


return False<EOL>

Handle a DELETE request natively.

        This method is called by the DELETE handler after checking for valid
        request syntax and making sure that there are no conflicting locks and
        If-headers.
        Depending on the return value, this provider can control further
        processing:

        False:
            handle_delete() did not do anything. WsgiDAV will process the request
            by calling delete() for every resource, bottom-up.
        True:
            handle_delete() has successfully performed the DELETE request.
            HTTP_NO_CONTENT will be reported to the DAV client.
        List of errors:
            handle_delete() tried to perform the delete request, but failed
            completely or partially. A list of errors is returned like
            ``[ (<ref-url>, <DAVError>), ... ]``
            These errors will be reported to the client.
        DAVError raised:
            handle_delete() refuses to perform the delete request. The DAVError
            will be reported to the client.

        An implementation may choose to apply other semantics and return True.
        For example deleting '/by_tag/cool/myres' may simply remove the 'cool'
        tag from 'my_res'.
        In this case, the resource might still be available by other URLs, so
        locks and properties are not removed.

        This default implementation returns ``False``, so standard processing
        takes place.

        Implementation of this method is OPTIONAL.


assert self.is_collection<EOL>raise NotImplementedError<EOL>

Return True, if delete() may be called on non-empty collections
        (see comments there).

        This method MUST be implemented for collections (not called on
        non-collections).


raise NotImplementedError<EOL>

Remove this resource (recursive).

        Preconditions (ensured by caller):

          - there are no conflicting locks or If-headers
          - if support_recursive_delete() is False, and this is a collection,
            all members have already been deleted.

        When support_recursive_delete is True, this method must be prepared to
        handle recursive deletes. This implies that child errors must be
        reported as tuple list [ (<ref-url>, <DAVError>), ... ].
        See http://www.webdav.org/specs/rfc4918.html#delete-collections

        This function

          - removes this resource
          - if this is a non-empty collection, also removes all members.
            Note that this may only occur, if support_recursive_delete is True.
          - For recursive deletes, return a list of error tuples for all failed
            resource paths.
          - removes associated direct locks
          - removes associated dead properties
          - raises HTTP_FORBIDDEN for read-only resources
          - raises HTTP_INTERNAL_ERROR on error

        This method MUST be implemented by all providers that support write
        access.


def handle_copy(self, dest_path, depth_infinity):

return False<EOL>

Handle a COPY request natively.

        This method is called by the COPY handler after checking for valid
        request syntax and making sure that there are no conflicting locks and
        If-headers.
        Depending on the return value, this provider can control further
        processing:

        False:
            handle_copy() did not do anything. WsgiDAV will process the request
            by calling copy_move_single() for every resource, bottom-up.
        True:
            handle_copy() has successfully performed the COPY request.
            HTTP_NO_CONTENT/HTTP_CREATED will be reported to the DAV client.
        List of errors:
            handle_copy() tried to perform the copy request, but failed
            completely or partially. A list of errors is returned like
            ``[ (<ref-url>, <DAVError>), ... ]``
            These errors will be reported to the client.
        DAVError raised:
            handle_copy() refuses to perform the copy request. The DAVError
            will be reported to the client.

        An implementation may choose to apply other semantics and return True.
        For example copying '/by_tag/cool/myres' to '/by_tag/hot/myres' may
        simply add a 'hot' tag.
        In this case, the resource might still be available by other URLs, so
        locks and properties are not removed.

        This default implementation returns ``False``, so standard processing
        takes place.

        Implementation of this method is OPTIONAL.


def copy_move_single(self, dest_path, is_move):

raise NotImplementedError<EOL>

Copy or move this resource to destPath (non-recursive).

        Preconditions (ensured by caller):

          - there must not be any conflicting locks on destination
          - overwriting is only allowed (i.e. destPath exists), when source and
            dest are of the same type ((non-)collections) and a Overwrite='T'
            was passed
          - destPath must not be a child path of this resource

        This function

          - Overwrites non-collections content, if destination exists.
          - MUST NOT copy collection members.
          - MUST NOT copy locks.
          - SHOULD copy live properties, when appropriate.
            E.g. displayname should be copied, but creationdate should be
            reset if the target did not exist before.
            See http://www.webdav.org/specs/rfc4918.html#dav.properties
          - SHOULD copy dead properties.
          - raises HTTP_FORBIDDEN for read-only providers
          - raises HTTP_INTERNAL_ERROR on error

        When is_move is True,

          - Live properties should be moved too (e.g. creationdate)
          - Non-collections must be moved, not copied
          - For collections, this function behaves like in copy-mode:
            detination collection must be created and properties are copied.
            Members are NOT created.
            The source collection MUST NOT be removed.

        This method MUST be implemented by all providers that support write
        access.


return False<EOL>

Handle a MOVE request natively.

        This method is called by the MOVE handler after checking for valid
        request syntax and making sure that there are no conflicting locks and
        If-headers.
        Depending on the return value, this provider can control further
        processing:

        False:
            handle_move() did not do anything. WsgiDAV will process the request
            by calling delete() and copy_move_single() for every resource,
            bottom-up.
        True:
            handle_move() has successfully performed the MOVE request.
            HTTP_NO_CONTENT/HTTP_CREATED will be reported to the DAV client.
        List of errors:
            handle_move() tried to perform the move request, but failed
            completely or partially. A list of errors is returned like
            ``[ (<ref-url>, <DAVError>), ... ]``
            These errors will be reported to the client.
        DAVError raised:
            handle_move() refuses to perform the move request. The DAVError
            will be reported to the client.

        An implementation may choose to apply other semantics and return True.
        For example moving '/by_tag/cool/myres' to '/by_tag/hot/myres' may
        simply remove the 'cool' tag from 'my_res' and add a 'hot' tag instead.
        In this case, the resource might still be available by other URLs, so
        locks and properties are not removed.

        This default implementation returns ``False``, so standard processing
        takes place.

        Implementation of this method is OPTIONAL.


Return True, if move_recursive() is available (see comments there).


raise DAVError(HTTP_FORBIDDEN)<EOL>

Move this resource and members to destPath.

        This method is only called, when support_recursive_move() returns True.

        MOVE is frequently used by clients to rename a file without changing its
        parent collection, so it's not appropriate to reset all live properties
        that are set at resource creation. For example, the DAV:creationdate
        property value SHOULD remain the same after a MOVE.

        Preconditions (ensured by caller):

          - there must not be any conflicting locks or If-header on source
          - there must not be any conflicting locks or If-header on destination
          - destPath must not exist
          - destPath must not be a member of this resource

        This method must be prepared to handle recursive moves. This implies
        that child errors must be reported as tuple list
        [ (<ref-url>, <DAVError>), ... ].
        See http://www.webdav.org/specs/rfc4918.html#move-collections

        This function

          - moves this resource and all members to destPath.
          - MUST NOT move associated locks.
            Instead, if the source (or children thereof) have locks, then
            these locks should be removed.
          - SHOULD maintain associated live properties, when applicable
            See http://www.webdav.org/specs/rfc4918.html#dav.properties
          - MUST maintain associated dead properties
          - raises HTTP_FORBIDDEN for read-only resources
          - raises HTTP_INTERNAL_ERROR on error

        An implementation may choose to apply other semantics.
        For example copying '/by_tag/cool/myres' to '/by_tag/new/myres' may
        simply add a 'new' tag to 'my_res'.

        This method is only called, when self.support_recursive_move() returns
        True. Otherwise, the request server implements MOVE using delete/copy.

        This method MAY be implemented in order to improve performance.


def resolve(self, script_name, path_info):

raise NotImplementedError<EOL>

Return a _DAVResource object for the path (None, if not found).

        `path_info`: is a URL relative to this object.

        DAVCollection.resolve() provides an implementation.


def finalize_headers(self, environ, response_headers):

pass<EOL>

Perform custom operations on the response headers.

        This gets called before the response is started.
        It enables adding additional headers or modifying the default ones.


raise NotImplementedError<EOL>

Returns the byte length of the content.

        MUST be implemented.

        See also _DAVResource.get_content_length()


raise NotImplementedError<EOL>

Contains the Content-Type header returned by a GET without accept
        headers.

        This getcontenttype property MUST be defined on any DAV compliant
        resource that returns the Content-Type header in response to a GET.
        See http://www.webdav.org/specs/rfc4918.html#PROPERTY_getcontenttype


raise NotImplementedError<EOL>

Open content as a stream for reading.

        Returns a file-like object / stream containing the contents of the
        resource specified.
        The application will close() the stream.

        This method MUST be implemented by all providers.


return False<EOL>

Return True, if this non-resource supports Range on GET requests.

        This default implementation returns False.


raise DAVError(HTTP_FORBIDDEN)<EOL>


pass<EOL>

Called when PUT has finished writing.

        This is only a notification that MAY be handled.


if path_info in ("<STR_LIT>", "<STR_LIT:/>"):<EOL><INDENT>return self<EOL><DEDENT>return None<EOL>

Return a _DAVResource object for the path (None, if not found).

        Since non-collection don't have members, we return None if path is not
        empty.


raise DAVError(HTTP_FORBIDDEN)<EOL>

Create and return an empty (length-0) resource as member of self.

        Called for LOCK requests on unmapped URLs.

        Preconditions (to be ensured by caller):

          - this must be a collection
          - <self.path + name> must not exist
          - there must be no conflicting locks

        Returns a DAVResuource.

        This method MUST be implemented by all providers that support write
        access.
        This default implementation simply raises HTTP_FORBIDDEN.


Create a new collection as member of self.

        Preconditions (to be ensured by caller):

          - this must be a collection
          - <self.path + name> must not exist
          - there must be no conflicting locks

        This method MUST be implemented by all providers that support write
        access.
        This default implementation raises HTTP_FORBIDDEN.


assert self.is_collection<EOL>return self.provider.get_resource_inst(<EOL>util.join_uri(self.path, name), self.environ<EOL>)<EOL>

Return child resource with a given name (None, if not found).

        This method COULD be overridden by a derived class, for performance
        reasons.
        This default implementation calls self.provider.get_resource_inst().


Return list of (direct) collection member names (UTF-8 byte strings).

        This method MUST be implemented.


return False<EOL>

Return True, if delete() may be called on non-empty collections
        (see comments there).

        This default implementation returns False.


raise DAVError(HTTP_FORBIDDEN)<EOL>

Remove this resource (possibly recursive).

        This method MUST be implemented if resource allows write access.

        See _DAVResource.delete()


raise DAVError(HTTP_FORBIDDEN)<EOL>

Copy or move this resource to destPath (non-recursive).

        This method MUST be implemented if resource allows write access.

        See _DAVResource.copy_move_single()


return False<EOL>

Return True, if move_recursive() is available (see comments there).


raise DAVError(HTTP_FORBIDDEN)<EOL>

Move this resource and members to destPath.

        This method MAY be implemented in order to improve performance.


if path_info in ("<STR_LIT>", "<STR_LIT:/>"):<EOL><INDENT>return self<EOL><DEDENT>assert path_info.startswith("<STR_LIT:/>")<EOL>name, rest = util.pop_path(path_info)<EOL>res = self.get_member(name)<EOL>if res is None or rest in ("<STR_LIT>", "<STR_LIT:/>"):<EOL><INDENT>return res<EOL><DEDENT>return res.resolve(util.join_uri(script_name, name), rest)<EOL>

Return a _DAVResource object for the path (None, if not found).

        `path_info`: is a URL relative to this object.


assert mount_path in ("<STR_LIT>", "<STR_LIT:/>") or not mount_path.endswith("<STR_LIT:/>")<EOL>self.mount_path = mount_path<EOL>

Set application root for this resource provider.

        This is the value of SCRIPT_NAME, when WsgiDAVApp is called.


<EOL>assert share_path == "<STR_LIT>" or share_path.startswith("<STR_LIT:/>")<EOL>if share_path == "<STR_LIT:/>":<EOL><INDENT>share_path = "<STR_LIT>"  <EOL><DEDENT>assert share_path in ("<STR_LIT>", "<STR_LIT:/>") or not share_path.endswith("<STR_LIT:/>")<EOL>self.share_path = share_path<EOL>

Set application location for this resource provider.

        @param share_path: a UTF-8 encoded, unquoted byte string.


return "<STR_LIT:/>" + compat.unquote(util.lstripstr(ref_url, self.share_path)).lstrip(<EOL>"<STR_LIT:/>"<EOL>)<EOL>

Convert a refUrl to a path, by stripping the share prefix.

        Used to calculate the <path> from a storage key by inverting get_ref_url().


def get_resource_inst(self, path, environ):

raise NotImplementedError<EOL>

Return a _DAVResource object for path.

        Should be called only once per request and resource::

            res = provider.get_resource_inst(path, environ)
            if res and not res.is_collection:
                print(res.get_content_type())

        If <path> does not exist, None is returned.
        <environ> may be used by the provider to implement per-request caching.

        See _DAVResource for details.

        This method MUST be implemented.


return self.get_resource_inst(path, environ) is not None<EOL>

Return True, if path maps to an existing resource.

        This method should only be used, if no other information is queried
        for <path>. Otherwise a _DAVResource should be created first.

        This method SHOULD be overridden by a more efficient implementation.


res = self.get_resource_inst(path, environ)<EOL>return res and res.is_collection<EOL>

Return True, if path maps to an existing collection resource.

        This method should only be used, if no other information is queried
        for <path>. Otherwise a _DAVResource should be created first.


def custom_request_handler(self, environ, start_response, default_handler):

return default_handler(environ, start_response)<EOL>

Optionally implement custom request handling.

        requestmethod = environ["REQUEST_METHOD"]
        Either

        - handle the request completely
        - do additional processing and call default_handler(environ, start_response)


<EOL>return u.encode(_filesystemencoding, "<STR_LIT>").decode("<STR_LIT>")<EOL>

Convert an environment variable to a WSGI 'bytes-as-unicode' string.


<EOL>return s.encode("<STR_LIT>")<EOL>

Convert a native string to a WSGI / HTTP compatible byte string.


assert not self.is_collection<EOL>return open(self._file_path, "<STR_LIT:rb>", BUFFER_SIZE)<EOL>

Open content as a stream for reading.

        See DAVResource.get_content()


assert not self.is_collection<EOL>if self.provider.readonly:<EOL><INDENT>raise DAVError(HTTP_FORBIDDEN)<EOL><DEDENT>return open(self._file_path, "<STR_LIT:wb>", BUFFER_SIZE)<EOL>

Open content as a stream for writing.

        See DAVResource.begin_write()


if self.provider.readonly:<EOL><INDENT>raise DAVError(HTTP_FORBIDDEN)<EOL><DEDENT>os.unlink(self._file_path)<EOL>self.remove_all_properties(True)<EOL>self.remove_all_locks(True)<EOL>

Remove this resource or collection (recursive).

        See DAVResource.delete()


if self.provider.readonly:<EOL><INDENT>raise DAVError(HTTP_FORBIDDEN)<EOL><DEDENT>fpDest = self.provider._loc_to_file_path(dest_path, self.environ)<EOL>assert not util.is_equal_or_child_uri(self.path, dest_path)<EOL>shutil.copy2(self._file_path, fpDest)<EOL>propMan = self.provider.prop_manager<EOL>if propMan:<EOL><INDENT>destRes = self.provider.get_resource_inst(dest_path, self.environ)<EOL>if is_move:<EOL><INDENT>propMan.move_properties(<EOL>self.get_ref_url(),<EOL>destRes.get_ref_url(),<EOL>with_children=False,<EOL>environ=self.environ,<EOL>)<EOL><DEDENT>else:<EOL><INDENT>propMan.copy_properties(<EOL>self.get_ref_url(), destRes.get_ref_url(), self.environ<EOL>)<EOL><DEDENT><DEDENT>


return True<EOL>


if self.provider.readonly:<EOL><INDENT>raise DAVError(HTTP_FORBIDDEN)<EOL><DEDENT>fpDest = self.provider._loc_to_file_path(dest_path, self.environ)<EOL>assert not util.is_equal_or_child_uri(self.path, dest_path)<EOL>assert not os.path.exists(fpDest)<EOL>_logger.debug("<STR_LIT>".format(self._file_path, fpDest))<EOL>shutil.move(self._file_path, fpDest)<EOL>if self.provider.prop_manager:<EOL><INDENT>destRes = self.provider.get_resource_inst(dest_path, self.environ)<EOL>self.provider.prop_manager.move_properties(<EOL>self.get_ref_url(),<EOL>destRes.get_ref_url(),<EOL>with_children=True,<EOL>environ=self.environ,<EOL>)<EOL><DEDENT>


<EOL>secs = util.parse_time_string(time_stamp)<EOL>if not dry_run:<EOL><INDENT>os.utime(self._file_path, (secs, secs))<EOL><DEDENT>return True<EOL>

Set last modified time for destPath to timeStamp on epoch-format


<EOL>nameList = []<EOL>assert compat.is_unicode(self._file_path)<EOL>for name in os.listdir(self._file_path):<EOL><INDENT>if not compat.is_unicode(name):<EOL><INDENT>name = name.decode(sys.getfilesystemencoding())<EOL><DEDENT>assert compat.is_unicode(name)<EOL>fp = os.path.join(self._file_path, name)<EOL>if not os.path.isdir(fp) and not os.path.isfile(fp):<EOL><INDENT>_logger.debug("<STR_LIT>".format(fp))<EOL>continue<EOL><DEDENT>name = compat.to_native(name)<EOL>nameList.append(name)<EOL><DEDENT>return nameList<EOL>

Return list of direct collection member names (utf-8 encoded).

        See DAVCollection.get_member_names()


assert compat.is_native(name), "<STR_LIT>".format(name)<EOL>fp = os.path.join(self._file_path, compat.to_unicode(name))<EOL>path = util.join_uri(self.path, name)<EOL>if os.path.isdir(fp):<EOL><INDENT>res = FolderResource(path, self.environ, fp)<EOL><DEDENT>elif os.path.isfile(fp):<EOL><INDENT>res = FileResource(path, self.environ, fp)<EOL><DEDENT>else:<EOL><INDENT>_logger.debug("<STR_LIT>".format(path))<EOL>res = None<EOL><DEDENT>return res<EOL>

Return direct collection member (DAVResource or derived).

        See DAVCollection.get_member()


assert "<STR_LIT:/>" not in name<EOL>if self.provider.readonly:<EOL><INDENT>raise DAVError(HTTP_FORBIDDEN)<EOL><DEDENT>path = util.join_uri(self.path, name)<EOL>fp = self.provider._loc_to_file_path(path, self.environ)<EOL>f = open(fp, "<STR_LIT:wb>")<EOL>f.close()<EOL>return self.provider.get_resource_inst(path, self.environ)<EOL>

Create an empty (length-0) resource.

        See DAVResource.create_empty_resource()


assert "<STR_LIT:/>" not in name<EOL>if self.provider.readonly:<EOL><INDENT>raise DAVError(HTTP_FORBIDDEN)<EOL><DEDENT>path = util.join_uri(self.path, name)<EOL>fp = self.provider._loc_to_file_path(path, self.environ)<EOL>os.mkdir(fp)<EOL>

Create a new collection as member of self.

        See DAVResource.create_collection()


if self.provider.readonly:<EOL><INDENT>raise DAVError(HTTP_FORBIDDEN)<EOL><DEDENT>fpDest = self.provider._loc_to_file_path(dest_path, self.environ)<EOL>assert not util.is_equal_or_child_uri(self.path, dest_path)<EOL>if not os.path.exists(fpDest):<EOL><INDENT>os.mkdir(fpDest)<EOL><DEDENT>try:<EOL><INDENT>shutil.copystat(self._file_path, fpDest)<EOL><DEDENT>except Exception:<EOL><INDENT>_logger.exception("<STR_LIT>".format(self._file_path))<EOL><DEDENT>propMan = self.provider.prop_manager<EOL>if propMan:<EOL><INDENT>destRes = self.provider.get_resource_inst(dest_path, self.environ)<EOL>if is_move:<EOL><INDENT>propMan.move_properties(<EOL>self.get_ref_url(),<EOL>destRes.get_ref_url(),<EOL>with_children=False,<EOL>environ=self.environ,<EOL>)<EOL><DEDENT>else:<EOL><INDENT>propMan.copy_properties(<EOL>self.get_ref_url(), destRes.get_ref_url(), self.environ<EOL>)<EOL><DEDENT><DEDENT>


return True<EOL>

Return True, if move_recursive() is available (see comments there).


def _loc_to_file_path(self, path, environ=None):

root_path = self.root_folder_path<EOL>assert root_path is not None<EOL>assert compat.is_native(root_path)<EOL>assert compat.is_native(path)<EOL>path_parts = path.strip("<STR_LIT:/>").split("<STR_LIT:/>")<EOL>file_path = os.path.abspath(os.path.join(root_path, *path_parts))<EOL>if not file_path.startswith(root_path):<EOL><INDENT>raise RuntimeError(<EOL>"<STR_LIT>".format(<EOL>file_path<EOL>)<EOL>)<EOL><DEDENT>file_path = util.to_unicode_safe(file_path)<EOL>return file_path<EOL>

Convert resource path to a unicode absolute file path.
        Optional environ argument may be useful e.g. in relation to per-user
        sub-folder chrooting inside root_folder_path.


self._count_get_resource_inst += <NUM_LIT:1><EOL>fp = self._loc_to_file_path(path, environ)<EOL>if not os.path.exists(fp):<EOL><INDENT>return None<EOL><DEDENT>if os.path.isdir(fp):<EOL><INDENT>return FolderResource(path, environ, fp)<EOL><DEDENT>return FileResource(path, environ, fp)<EOL>

Return info dictionary for path.

        See DAVProvider.get_resource_inst()


def compute_digest_response(<EOL>self, realm, user_name, method, uri, nonce, cnonce, qop, nc, environ<EOL>):

def md5h(data):<EOL><INDENT>return md5(compat.to_bytes(data)).hexdigest()<EOL><DEDENT>def md5kd(secret, data):<EOL><INDENT>return md5h(secret + "<STR_LIT::>" + data)<EOL><DEDENT>A1 = self.domain_controller.digest_auth_user(realm, user_name, environ)<EOL>if not A1:<EOL><INDENT>return False<EOL><DEDENT>A2 = method + "<STR_LIT::>" + uri<EOL>if qop:<EOL><INDENT>res = md5kd(<EOL>A1, nonce + "<STR_LIT::>" + nc + "<STR_LIT::>" + cnonce + "<STR_LIT::>" + qop + "<STR_LIT::>" + md5h(A2)<EOL>)<EOL><DEDENT>else:<EOL><INDENT>res = md5kd(A1, nonce + "<STR_LIT::>" + md5h(A2))<EOL><DEDENT>return res<EOL>

Computes digest hash.

        Calculation of the A1 (HA1) part is delegated to the dc interface method
        `digest_auth_user()`.

        Args:
            realm (str):
            user_name (str):
            method (str): WebDAV Request Method
            uri (str):
            nonce (str): server generated nonce value
            cnonce (str): client generated cnonce value
            qop (str): quality of protection
            nc (str) (number), nonce counter incremented by client
        Returns:
            MD5 hash string
            or False if user rejected by domain controller


if hasattr(v, "<STR_LIT:value>"):<EOL><INDENT>return int(v.value)  <EOL><DEDENT>else:<EOL><INDENT>return int(v)<EOL><DEDENT>

Return HTTP response code as integer, e.g. 204.


code = get_http_status_code(v)<EOL>try:<EOL><INDENT>return ERROR_DESCRIPTIONS[code]<EOL><DEDENT>except KeyError:<EOL><INDENT>return "<STR_LIT>".format(code)<EOL><DEDENT>

Return HTTP response string, e.g. 204 -> ('204 No Content').
    The return string always includes descriptive text, to satisfy Apache mod_dav.

    `v`: status code or DAVError


if isinstance(e, DAVError):<EOL><INDENT>return e<EOL><DEDENT>elif isinstance(e, Exception):<EOL><INDENT>return DAVError(HTTP_INTERNAL_ERROR, src_exception=e)<EOL><DEDENT>else:<EOL><INDENT>return DAVError(HTTP_INTERNAL_ERROR, "<STR_LIT:{}>".format(e))<EOL><DEDENT>

Convert any non-DAVError exception to HTTP_INTERNAL_ERROR.


if self.value in ERROR_DESCRIPTIONS:<EOL><INDENT>s = "<STR_LIT:{}>".format(ERROR_DESCRIPTIONS[self.value])<EOL><DEDENT>else:<EOL><INDENT>s = "<STR_LIT:{}>".format(self.value)<EOL><DEDENT>if self.context_info:<EOL><INDENT>s += "<STR_LIT>".format(self.context_info)<EOL><DEDENT>elif self.value in ERROR_RESPONSES:<EOL><INDENT>s += "<STR_LIT>".format(ERROR_RESPONSES[self.value])<EOL><DEDENT>if self.src_exception:<EOL><INDENT>s += "<STR_LIT>".format(self.src_exception)<EOL><DEDENT>if self.err_condition:<EOL><INDENT>s += "<STR_LIT>".format(self.err_condition)<EOL><DEDENT>return s<EOL>