def dowaitchanged(self, uri, etag, user, pswd, label=""):

        for _ignore in range(self.manager.server_info.waitcount):
            req = request(self.manager)
            req.method = "HEAD"
            req.ruris.append(uri)
            req.ruri = uri
            if user:
                req.user = user
            if pswd:
                req.pswd = pswd
            result, _ignore_resulttxt, response, _ignore_respdata = self.dorequest(req, False, False, label="%s | %s" % (label, "WAITCHANGED"))
            if result and (response is not None):
                if response.status / 100 == 2:
                    hdrs = response.msg.getheaders("Etag")
                    if hdrs:
                        newetag = hdrs[0].encode("utf-8")
                        if newetag != etag:
                            break
                else:
                    return False
            delay = self.manager.server_info.waitdelay
            starttime = time.time()
            while (time.time() < starttime + delay):
                pass
        else:
            return False

        return True
Exemple #2
0
    def dowaitchanged(self, original_request, uri, etag, user, pswd, label=""):

        for _ignore in range(self.manager.server_info.waitcount):
            req = request(self.manager)
            req.method = "HEAD"
            req.host = original_request.host
            req.port = original_request.port
            req.ruris.append(uri)
            req.ruri = uri
            if user:
                req.user = user
            if pswd:
                req.pswd = pswd
            result, _ignore_resulttxt, response, _ignore_respdata = self.dorequest(req, False, False, label="%s | %s" % (label, "WAITCHANGED"))
            if result and (response is not None):
                if response.status / 100 == 2:
                    hdrs = response.msg.getheaders("Etag")
                    if hdrs:
                        newetag = hdrs[0].encode("utf-8")
                        if newetag != etag:
                            break
                else:
                    return False
            delay = self.manager.server_info.waitdelay
            starttime = time.time()
            while (time.time() < starttime + delay):
                pass
        else:
            return False

        return True
Exemple #3
0
    def dowaitcount(self, original_request, collection, count, label=""):

        hrefs = []
        for _ignore in range(self.manager.server_info.waitcount):
            req = request(self.manager)
            req.method = "PROPFIND"
            req.host = original_request.host
            req.port = original_request.port
            req.ruris.append(collection[0])
            req.ruri = collection[0]
            req.headers["Depth"] = "1"
            if len(collection[1]):
                req.user = collection[1]
            if len(collection[2]):
                req.pswd = collection[2]
            req.data = data(self.manager)
            req.data.value = """<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getetag/>
</D:prop>
</D:propfind>
"""
            req.data.content_type = "text/xml"
            result, _ignore_resulttxt, response, respdata = self.dorequest(req, False, False, label="%s | %s %d" % (label, "WAITCOUNT", count))
            hrefs = []
            if result and (response is not None) and (response.status == 207) and (respdata is not None):
                tree = ElementTree(file=StringIO(respdata))

                for response in tree.findall("{DAV:}response"):
                    href = response.findall("{DAV:}href")[0]
                    if href.text.rstrip("/") != collection[0].rstrip("/"):
                        hrefs.append(href.text)

                if len(hrefs) == count:
                    return True, None
            delay = self.manager.server_info.waitdelay
            starttime = time.time()
            while (time.time() < starttime + delay):
                pass

        if self.manager.debug and hrefs:
            # Get the content of each resource
            rdata = ""
            for href in hrefs:
                result, respdata = self.doget(req, (href, collection[1], collection[2],), label)
                test = "unknown"
                if respdata.startswith("BEGIN:VCALENDAR"):
                    uid = respdata.find("UID:")
                    if uid != -1:
                        uid = respdata[uid + 4:uid + respdata[uid:].find("\r\n")]
                        test = self.uidmaps.get(uid, "unknown")
                rdata += "\n\nhref: {h}\ntest: {t}\n\n{r}\n".format(h=href, t=test, r=respdata)

            return False, rdata
        else:
            return False, len(hrefs)
Exemple #4
0
    def dowaitcount(self, original_request, collection, count, label=""):

        hrefs = []
        for _ignore in range(self.manager.server_info.waitcount):
            req = request(self.manager)
            req.method = "PROPFIND"
            req.host = original_request.host
            req.port = original_request.port
            req.ruris.append(collection[0])
            req.ruri = collection[0]
            req.headers["Depth"] = "1"
            if len(collection[1]):
                req.user = collection[1]
            if len(collection[2]):
                req.pswd = collection[2]
            req.data = data(self.manager)
            req.data.value = """<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getetag/>
</D:prop>
</D:propfind>
"""
            req.data.content_type = "text/xml"
            result, _ignore_resulttxt, response, respdata = self.dorequest(req, False, False, label="%s | %s %d" % (label, "WAITCOUNT", count))
            hrefs = []
            if result and (response is not None) and (response.status == 207) and (respdata is not None):
                tree = ElementTree(file=StringIO(respdata))

                for response in tree.findall("{DAV:}response"):
                    href = response.findall("{DAV:}href")[0]
                    if href.text.rstrip("/") != collection[0].rstrip("/"):
                        hrefs.append(href.text)

                if len(hrefs) == count:
                    return True, None
            delay = self.manager.server_info.waitdelay
            starttime = time.time()
            while (time.time() < starttime + delay):
                pass

        if self.manager.debug and hrefs:
            # Get the content of each resource
            rdata = ""
            for href in hrefs:
                result, respdata = self.doget(req, (href, collection[1], collection[2],), label)
                test = "unknown"
                if respdata.startswith("BEGIN:VCALENDAR"):
                    uid = respdata.find("UID:")
                    if uid != -1:
                        uid = respdata[uid + 4:uid + respdata[uid:].find("\r\n")]
                        test = self.uidmaps.get(uid, "unknown")
                rdata += "\n\nhref: {h}\ntest: {t}\n\n{r}\n".format(h=href, t=test, r=respdata)

            return False, rdata
        else:
            return False, len(hrefs)
Exemple #5
0
def getResponse(data):
    try:
        rqst = request.request(data)
        uri = rqst.getURI()
        uidx = urlMapper[uri]
        if uidx != None:
            return uidx.getFun()(rqst, uidx.getTemplate())
    except ValueError, e:
        print e
        return None
 def dodeleteall(self, deletes, label=""):
     if len(deletes) == 0:
         return True
     for deleter in deletes:
         req = request(self.manager)
         req.method = "DELETE"
         req.ruris.append(deleter[0])
         req.ruri = deleter[0]
         if len(deleter[1]):
             req.user = deleter[1]
         if len(deleter[2]):
             req.pswd = deleter[2]
         self.dorequest(req, False, False, label=label)
    def doget(self, resource, label=""):
        req = request(self.manager)
        req.method = "GET"
        req.ruris.append(resource[0])
        req.ruri = resource[0]
        if len(resource[1]):
            req.user = resource[1]
        if len(resource[2]):
            req.pswd = resource[2]
        _ignore_result, _ignore_resulttxt, response, respdata = self.dorequest(req, False, False, label=label)
        if response.status / 100 != 2:
            return False, None

        return True, respdata
 def doenddelete(self, description, label=""):
     if len(self.end_deletes) == 0:
         return True
     self.manager.message("trace", "Start: " + description)
     for deleter in self.end_deletes:
         req = request(self.manager)
         req.method = "DELETE"
         req.ruris.append(deleter[0])
         req.ruri = deleter[0]
         if len(deleter[1]):
             req.user = deleter[1]
         if len(deleter[2]):
             req.pswd = deleter[2]
         self.dorequest(req, False, False, label=label)
     self.manager.message("trace", "{name:<60}{value:>10}".format(name="End: " + description, value="[DONE]"))
Exemple #9
0
    def dofindcontains(self, original_request, collection, match, label=""):
        hresult = ""

        uri = collection[0]
        req = request(self.manager)
        req.method = "PROPFIND"
        req.host = original_request.host
        req.port = original_request.port
        req.ruris.append(uri)
        req.ruri = uri
        req.headers["Depth"] = "1"
        if len(collection[1]):
            req.user = collection[1]
        if len(collection[2]):
            req.pswd = collection[2]
        req.data = data(self.manager)
        req.data.value = """<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getetag/>
</D:prop>
</D:propfind>
"""
        req.data.content_type = "text/xml"
        result, _ignore_resulttxt, response, respdata = self.dorequest(req, False, False, label="%s | %s" % (label, "FINDNEW"))
        if result and (response is not None) and (response.status == 207) and (respdata is not None):
            try:
                tree = ElementTree(file=StringIO(respdata))
            except Exception:
                return hresult

            request_uri = req.getURI(self.manager.server_info)
            for response in tree.findall("{DAV:}response"):

                # Get href for this response
                href = response.findall("{DAV:}href")
                if len(href) != 1:
                    return False, "           Wrong number of DAV:href elements\n"
                href = href[0].text
                if href != request_uri:

                    _ignore_result, respdata = self.doget(req, (href, collection[1], collection[2],), label)
                    if respdata.find(match) != -1:
                        break
            else:
                href = None

        return href
Exemple #10
0
    def dofindcontains(self, original_request, collection, match, label=""):
        hresult = ""

        uri = collection[0]
        req = request(self.manager)
        req.method = "PROPFIND"
        req.host = original_request.host
        req.port = original_request.port
        req.ruris.append(uri)
        req.ruri = uri
        req.headers["Depth"] = "1"
        if len(collection[1]):
            req.user = collection[1]
        if len(collection[2]):
            req.pswd = collection[2]
        req.data = data(self.manager)
        req.data.value = """<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getetag/>
</D:prop>
</D:propfind>
"""
        req.data.content_type = "text/xml"
        result, _ignore_resulttxt, response, respdata = self.dorequest(req, False, False, label="%s | %s" % (label, "FINDNEW"))
        if result and (response is not None) and (response.status == 207) and (respdata is not None):
            try:
                tree = ElementTree(file=StringIO(respdata))
            except Exception:
                return hresult

            request_uri = req.getURI(self.manager.server_info)
            for response in tree.findall("{DAV:}response"):

                # Get href for this response
                href = response.findall("{DAV:}href")
                if len(href) != 1:
                    return False, "           Wrong number of DAV:href elements\n"
                href = href[0].text
                if href != request_uri:

                    _ignore_result, respdata = self.doget(req, (href, collection[1], collection[2],), label)
                    if respdata.find(match) != -1:
                        break
            else:
                href = None

        return href
Exemple #11
0
 def doenddelete(self, description, label=""):
     if len(self.end_deletes) == 0:
         return True
     self.manager.message("trace", "Start: " + description)
     for uri, delete_request in self.end_deletes:
         req = request(self.manager)
         req.method = "DELETE"
         req.host = delete_request.host
         req.port = delete_request.port
         req.ruris.append(uri)
         req.ruri = uri
         req.user = delete_request.user
         req.pswd = delete_request.pswd
         req.cert = delete_request.cert
         self.dorequest(req, False, False, label=label)
     self.manager.message("trace", "{name:<60}{value:>10}".format(name="End: " + description, value="[DONE]"))
 def doenddelete(self, description, label=""):
     if len(self.end_deletes) == 0:
         return True
     description += " " * max(1, STATUSTXT_WIDTH - len(description))
     self.manager.log(manager.LOG_HIGH, description, before=1, after=0)
     for deleter in self.end_deletes:
         req = request(self.manager)
         req.method = "DELETE"
         req.ruris.append(deleter[0])
         req.ruri = deleter[0]
         if len(deleter[1]):
             req.user = deleter[1]
         if len(deleter[2]):
             req.pswd = deleter[2]
         self.dorequest(req, False, False, label=label)
     self.manager.log(manager.LOG_HIGH, "[DONE]")
Exemple #13
0
 def doenddelete(self, description, label=""):
     if len(self.end_deletes) == 0:
         return True
     self.manager.message("trace", "Start: " + description)
     for uri, delete_request in self.end_deletes:
         req = request(self.manager)
         req.method = "DELETE"
         req.host = delete_request.host
         req.port = delete_request.port
         req.ruris.append(uri)
         req.ruri = uri
         req.user = delete_request.user
         req.pswd = delete_request.pswd
         req.cert = delete_request.cert
         self.dorequest(req, False, False, label=label)
     self.manager.message("trace", "{name:<60}{value:>10}".format(name="End: " + description, value="[DONE]"))
Exemple #14
0
    def doget(self, original_request, resource, label=""):
        req = request(self.manager)
        req.method = "GET"
        req.host = original_request.host
        req.port = original_request.port
        req.ruris.append(resource[0])
        req.ruri = resource[0]
        if len(resource[1]):
            req.user = resource[1]
        if len(resource[2]):
            req.pswd = resource[2]
        _ignore_result, _ignore_resulttxt, response, respdata = self.dorequest(req, False, False, label=label)
        if response.status / 100 != 2:
            return False, None

        return True, respdata
    def dodeleteall(self, deletes, label=""):
        if len(deletes) == 0:
            return True
        for deleter in deletes:
            req = request(self.manager)
            req.method = "DELETE"
            req.ruris.append(deleter[0])
            req.ruri = deleter[0]
            if len(deleter[1]):
                req.user = deleter[1]
            if len(deleter[2]):
                req.pswd = deleter[2]
            _ignore_result, _ignore_resulttxt, response, _ignore_respdata = self.dorequest(req, False, False, label=label)
            if response.status / 100 != 2:
                return False

        return True
    def dofindall( self, collection):
        hrefs = []
        req = request(self.manager)
        req.method = "PROPFIND"
        req.ruris.append(collection[0])
        req.ruri = collection[0]
        req.headers["Depth"] = "1"
        if len(collection[1]):
            req.user = collection[1]
        if len(collection[2]):
            req.pswd = collection[2]
        req.data = data()
        req.data.value = """<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getetag/>
</D:prop>
</D:propfind>
"""
        req.data.content_type = "text/xml"
        result, _ignore_resulttxt, response, respdata = self.dorequest( req, False, False )
        if result and (response is not None) and (response.status == 207) and (respdata is not None):
            doc = xml.dom.minidom.parseString( respdata )

            def ElementsByName(parent, nsURI, localName):
                rc = NodeList()
                for node in parent.childNodes:
                    if node.nodeType == Node.ELEMENT_NODE:
                        if ((localName == "*" or node.localName == localName) and
                            (nsURI == "*" or node.namespaceURI == nsURI)):
                            rc.append(node)
                return rc

            for response in doc.getElementsByTagNameNS( "DAV:", "response" ):
    
                # Get href for this response
                href = ElementsByName(response, "DAV:", "href")
                if len(href) != 1:
                    return False, "           Wrong number of DAV:href elements\n"
                if href[0].firstChild is not None:
                    href = href[0].firstChild.data
                    if href != req.ruri:
                        hrefs.append((href, collection[1], collection[2]) )
        return hrefs
Exemple #17
0
    def dodeleteall(self, original_request, deletes, label=""):
        if len(deletes) == 0:
            return True
        for deleter in deletes:
            req = request(self.manager)
            req.method = "DELETE"
            req.host = original_request.host
            req.port = original_request.port
            req.ruris.append(deleter[0])
            req.ruri = deleter[0]
            if len(deleter[1]):
                req.user = deleter[1]
            if len(deleter[2]):
                req.pswd = deleter[2]
            _ignore_result, _ignore_resulttxt, response, _ignore_respdata = self.dorequest(req, False, False, label=label)
            if response.status / 100 != 2:
                return False

        return True
    def dowaitcount(self, collection, count, label=""):

        for _ignore in range(self.manager.server_info.waitcount):
            req = request(self.manager)
            req.method = "PROPFIND"
            req.ruris.append(collection[0])
            req.ruri = collection[0]
            req.headers["Depth"] = "1"
            if len(collection[1]):
                req.user = collection[1]
            if len(collection[2]):
                req.pswd = collection[2]
            req.data = data()
            req.data.value = """<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getetag/>
</D:prop>
</D:propfind>
"""
            req.data.content_type = "text/xml"
            result, _ignore_resulttxt, response, respdata = self.dorequest(req, False, False, label="%s | %s %d" % (label, "WAITCOUNT", count))
            ctr = 0
            if result and (response is not None) and (response.status == 207) and (respdata is not None):
                tree = ElementTree(file=StringIO(respdata))

                for response in tree.findall("{DAV:}response"):
                    ctr += 1

                if ctr - 1 == count:
                    return None
            delay = self.manager.server_info.waitdelay
            starttime = time.time()
            while (time.time() < starttime + delay):
                pass
        else:
            return ctr - 1
    def dofindnew( self, collection, label = "" ):
        hresult = ""
        req = request(self.manager)
        req.method = "PROPFIND"
        req.ruris.append(collection[0])
        req.ruri = collection[0]
        req.headers["Depth"] = "1"
        if len(collection[1]):
            req.user = collection[1]
        if len(collection[2]):
            req.pswd = collection[2]
        req.data = data()
        req.data.value = """<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getetag/>
<D:getlastmodified/>
</D:prop>
</D:propfind>
"""
        req.data.content_type = "text/xml"
        result, _ignore_resulttxt, response, respdata = self.dorequest( req, False, False, label="%s | %s" % (label, "FINDNEW") )
        if result and (response is not None) and (response.status == 207) and (respdata is not None):
            try:
                tree = ElementTree(file=StringIO(respdata))
            except Exception:
                return hresult

            latest = 0
            request_uri = req.getURI( self.manager.server_info )
            same = []
            for response in tree.findall("{DAV:}response" ):
    
                # Get href for this response
                href = response.findall("{DAV:}href")
                if len(href) != 1:
                    return False, "           Wrong number of DAV:href elements\n"
                href = href[0].text
                if href != request_uri:

                    # Get all property status
                    propstatus = response.findall("{DAV:}propstat")
                    for props in propstatus:
                        # Determine status for this propstat
                        status = props.findall("{DAV:}status")
                        if len(status) == 1:
                            statustxt = status[0].text
                            status = False
                            if statustxt.startswith("HTTP/1.1 ") and (len(statustxt) >= 10):
                                status = (statustxt[9] == "2")
                        else:
                            status = False
                        
                        # Get properties for this propstat
                        prop = props.findall("{DAV:}prop")
                        for el in prop:

                            # Get properties for this propstat
                            glm = el.findall("{DAV:}getlastmodified")
                            if len(glm) != 1:
                                continue
                            value = glm[0].text
                            value = rfc822.parsedate(value)
                            value = time.mktime(value)
                            if value > latest:
                                hresult = href
                                latest = value
                                same = []
                            elif value == latest:
                                if len(same) == 0:
                                    same.append(hresult)
                                same.append(value)
                                

        if same:
            high_index = -1
            for href in same:
                try:
                    index = self.foundnew.index(href)
                except ValueError:
                    hresult = href
                    break
                if index > high_index:
                    hresult = href
                    high_index = index
        if hresult:
            self.foundnew.append(hresult)
        return hresult
    def dofindnew(self, collection, label="", other=False):
        hresult = ""

        uri = collection[0]
        if other:
            uri = self.manager.server_info.extrasubs(uri)
            skip = uri
            uri = "/".join(uri.split("/")[:-1]) + "/"
        else:
            skip = None
        possible_matches = set()
        req = request(self.manager)
        req.method = "PROPFIND"
        req.ruris.append(uri)
        req.ruri = uri
        req.headers["Depth"] = "1"
        if len(collection[1]):
            req.user = collection[1]
        if len(collection[2]):
            req.pswd = collection[2]
        req.data = data(self.manager)
        req.data.value = """<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getetag/>
<D:getlastmodified/>
</D:prop>
</D:propfind>
"""
        req.data.content_type = "text/xml"
        result, _ignore_resulttxt, response, respdata = self.dorequest(req, False, False, label="%s | %s" % (label, "FINDNEW"))
        if result and (response is not None) and (response.status == 207) and (respdata is not None):
            try:
                tree = ElementTree(file=StringIO(respdata))
            except Exception:
                return hresult

            latest = 0
            request_uri = req.getURI(self.manager.server_info)
            for response in tree.findall("{DAV:}response"):

                # Get href for this response
                href = response.findall("{DAV:}href")
                if len(href) != 1:
                    return False, "           Wrong number of DAV:href elements\n"
                href = href[0].text
                if href != request_uri and (not other or href != skip):

                    # Get all property status
                    propstatus = response.findall("{DAV:}propstat")
                    for props in propstatus:
                        # Determine status for this propstat
                        status = props.findall("{DAV:}status")
                        if len(status) == 1:
                            statustxt = status[0].text
                            status = False
                            if statustxt.startswith("HTTP/1.1 ") and (len(statustxt) >= 10):
                                status = (statustxt[9] == "2")
                        else:
                            status = False

                        if status:
                            # Get properties for this propstat
                            prop = props.findall("{DAV:}prop")
                            for el in prop:

                                # Get properties for this propstat
                                glm = el.findall("{DAV:}getlastmodified")
                                if len(glm) != 1:
                                    continue
                                value = glm[0].text
                                value = rfc822.parsedate(value)
                                value = time.mktime(value)
                                if value > latest:
                                    possible_matches.clear()
                                    possible_matches.add(href)
                                    latest = value
                                elif value == latest:
                                    possible_matches.add(href)
                        elif not hresult:
                            possible_matches.add(href)

        if len(possible_matches) == 1:
            hresult = possible_matches.pop()
        elif len(possible_matches) > 1:
            not_seen_before = possible_matches - self.previously_found
            if len(not_seen_before) == 1:
                hresult = not_seen_before.pop()
        if hresult:
            self.previously_found.add(hresult)
        return hresult
    def dofindnew( self, collection):
        hresult = ""
        req = request(self.manager)
        req.method = "PROPFIND"
        req.ruris.append(collection[0])
        req.ruri = collection[0]
        req.headers["Depth"] = "1"
        if len(collection[1]):
            req.user = collection[1]
        if len(collection[2]):
            req.pswd = collection[2]
        req.data = data()
        req.data.value = """<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getetag/>
<D:getlastmodified/>
</D:prop>
</D:propfind>
"""
        req.data.content_type = "text/xml"
        result, _ignore_resulttxt, response, respdata = self.dorequest( req, False, False )
        if result and (response is not None) and (response.status == 207) and (respdata is not None):
            doc = xml.dom.minidom.parseString( respdata )

            def ElementsByName(parent, nsURI, localName):
                rc = NodeList()
                for node in parent.childNodes:
                    if node.nodeType == Node.ELEMENT_NODE:
                        if ((localName == "*" or node.localName == localName) and
                            (nsURI == "*" or node.namespaceURI == nsURI)):
                            rc.append(node)
                return rc

            latest = 0
            for response in doc.getElementsByTagNameNS( "DAV:", "response" ):
    
                # Get href for this response
                href = ElementsByName(response, "DAV:", "href")
                if len(href) != 1:
                    return False, "           Wrong number of DAV:href elements\n"
                if href[0].firstChild is not None:
                    href = href[0].firstChild.data
                    if href != req.ruri:

                        # Get all property status
                        propstatus = ElementsByName(response, "DAV:", "propstat")
                        for props in propstatus:
                            # Determine status for this propstat
                            status = ElementsByName(props, "DAV:", "status")
                            if len(status) == 1:
                                statustxt = status[0].firstChild.data
                                status = False
                                if statustxt.startswith("HTTP/1.1 ") and (len(statustxt) >= 10):
                                    status = (statustxt[9] == "2")
                            else:
                                status = False
                            
                            # Get properties for this propstat
                            prop = ElementsByName(props, "DAV:", "prop")
                            for el in prop:
    
                                # Get properties for this propstat
                                glm = ElementsByName(el, "DAV:", "getlastmodified")
                                if len(glm) != 1:
                                    continue
                                if glm[0].firstChild is not None:
                                    value = glm[0].firstChild.data
                                    value = rfc822.parsedate(value)
                                    value = time.mktime(value)
                                    if value > latest:
                                        hresult = href
                                        latest = value

        return hresult
Exemple #22
0
    def dofindnew(self, original_request, collection, label="", other=False):
        hresult = ""

        uri = collection[0]
        if other:
            uri = self.manager.server_info.extrasubs(uri)
            skip = uri
            uri = "/".join(uri.split("/")[:-1]) + "/"
        else:
            skip = None
        possible_matches = set()
        req = request(self.manager)
        req.method = "PROPFIND"
        req.host = original_request.host
        req.port = original_request.port
        req.ruris.append(uri)
        req.ruri = uri
        req.headers["Depth"] = "1"
        if len(collection[1]):
            req.user = collection[1]
        if len(collection[2]):
            req.pswd = collection[2]
        req.data = data(self.manager)
        req.data.value = """<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getetag/>
<D:getlastmodified/>
</D:prop>
</D:propfind>
"""
        req.data.content_type = "text/xml"
        result, _ignore_resulttxt, response, respdata = self.dorequest(req, False, False, label="%s | %s" % (label, "FINDNEW"))
        if result and (response is not None) and (response.status == 207) and (respdata is not None):
            try:
                tree = ElementTree(file=StringIO(respdata))
            except Exception:
                return hresult

            latest = 0
            request_uri = req.getURI(self.manager.server_info)
            for response in tree.findall("{DAV:}response"):

                # Get href for this response
                href = response.findall("{DAV:}href")
                if len(href) != 1:
                    return False, "           Wrong number of DAV:href elements\n"
                href = href[0].text
                if href != request_uri and (not other or href != skip):

                    # Get all property status
                    propstatus = response.findall("{DAV:}propstat")
                    for props in propstatus:
                        # Determine status for this propstat
                        status = props.findall("{DAV:}status")
                        if len(status) == 1:
                            statustxt = status[0].text
                            status = False
                            if statustxt.startswith("HTTP/1.1 ") and (len(statustxt) >= 10):
                                status = (statustxt[9] == "2")
                        else:
                            status = False

                        if status:
                            # Get properties for this propstat
                            prop = props.findall("{DAV:}prop")
                            for el in prop:

                                # Get properties for this propstat
                                glm = el.findall("{DAV:}getlastmodified")
                                if len(glm) != 1:
                                    continue
                                value = glm[0].text
                                value = rfc822.parsedate(value)
                                value = time.mktime(value)
                                if value > latest:
                                    possible_matches.clear()
                                    possible_matches.add(href)
                                    latest = value
                                elif value == latest:
                                    possible_matches.add(href)
                        elif not hresult:
                            possible_matches.add(href)

        if len(possible_matches) == 1:
            hresult = possible_matches.pop()
        elif len(possible_matches) > 1:
            not_seen_before = possible_matches - self.previously_found
            if len(not_seen_before) == 1:
                hresult = not_seen_before.pop()
        if hresult:
            self.previously_found.add(hresult)
        return hresult