twisted.internet.defer.waitForDeferred

Here are the examples of the python api twisted.internet.defer.waitForDeferred taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

37 Examples 7

Example 1

Project: mythbox Source File: test_defgen.py
Function: genbasics
    def _genBasics(self):

        x = waitForDeferred(getThing())
        yield x
        x = x.getResult()

        self.assertEquals(x, "hi")

        ow = waitForDeferred(getOwie())
        yield ow
        try:
            ow.getResult()
        except ZeroDivisionError, e:
            self.assertEquals(str(e), 'OMG')
        yield "WOOSH"
        return

Example 2

Project: mythbox Source File: test_defgen.py
    def _genHandledTerminalFailure(self):
        x = waitForDeferred(defer.fail(TerminalException("Handled Terminal Failure")))
        yield x
        try:
            x.getResult()
        except TerminalException:
            pass

Example 3

Project: mythbox Source File: test_defgen.py
    def _genHandledTerminalAsyncFailure(self, d):
        x = waitForDeferred(d)
        yield x
        try:
            x.getResult()
        except TerminalException:
            pass

Example 4

Project: mythbox Source File: test_defgen.py
    def _genStackUsage(self):
        for x in range(5000):
            # Test with yielding a deferred
            x = waitForDeferred(defer.succeed(1))
            yield x
            x = x.getResult()
        yield 0

Example 5

Project: ccs-calendarserver Source File: test_pipeline.py
    @deferredGenerator
    def testAdvancedWorkingness(self):
        args = ('-u', util.sibpath(__file__, "tworequest_client.py"), "basic",
                str(self.port), self.type)
        d = waitForDeferred(utils.getProcessOutputAndValue(sys.executable,
                                                           args=args,
                                                           env=os.environ))
        yield d
        out, err, code = d.getResult()
        self.assertEquals(code, 0, "Error output:\n%s" % (err,))
        self.assertEquals(out, "HTTP/1.1 403 Forbidden\r\nContent-Length: 0\r\n\r\nHTTP/1.1 403 Forbidden\r\nContent-Length: 0\r\n\r\n")

Example 6

Project: ccs-calendarserver Source File: test_fileupload.py
    def doTest(self, boundary, data, expected_args, expected_files):
        # import time, gc, cgi, cStringIO
        for bytes in range(1, 20):
            # s = TestStream(data, maxReturn=bytes)
            s = stream.IStream(data)
            # t=time.time()
            d = waitForDeferred(fileupload.parseMultipartFormData(s, boundary))
            yield d
            args, files = d.getResult()
            # e=time.time()
            # print "%.2g"%(e-t)
            self.assertEquals(args, expected_args)

            # Read file data back into memory to compare.
            out = {}
            for name, l in files.items():
                out[name] = [(filename, ctype, f.read()) for (filename, ctype, f) in l]
            self.assertEquals(out, expected_files)

Example 7

Project: ccs-calendarserver Source File: test_fileupload.py
Function: do_test
    def doTest(self, data, expected_args):
        for bytes in range(1, 20):
            s = TestStream(data, maxReturn=bytes)
            d = waitForDeferred(fileupload.parse_urlencoded(s))
            yield d
            args = d.getResult()
            self.assertEquals(args, expected_args)

Example 8

Project: ccs-calendarserver Source File: test_http.py
    def testBasicWorkingness(self):
        args = ('-u', util.sibpath(__file__, "simple_client.py"), "basic",
                str(self.port), self.type)
        d = waitForDeferred(
            utils.getProcessOutputAndValue(sys.executable, args=args,
                                           env=os.environ)
        )
        yield d
        out, err, code = d.getResult()

        self.assertEquals(code, 0, "Error output:\n%s" % (err,))
        self.assertEquals(out, "HTTP/1.1 402 Payment Required\r\nContent-Length: 0\r\nConnection: close\r\n\r\n")

Example 9

Project: ccs-calendarserver Source File: test_http.py
    def testLingeringClose(self):
        args = ('-u', util.sibpath(__file__, "simple_client.py"),
                "lingeringClose", str(self.port), self.type)
        d = waitForDeferred(
            utils.getProcessOutputAndValue(sys.executable, args=args,
                                           env=os.environ)
        )
        yield d
        out, err, code = d.getResult()
        self.assertEquals(code, 0, "Error output:\n%s" % (err,))
        self.assertEquals(out, "HTTP/1.1 402 Payment Required\r\nContent-Length: 0\r\nConnection: close\r\n\r\n")

Example 10

Project: SubliminalCollaborator Source File: test_defgen.py
Function: genbasics
    def _genBasics(self):

        x = waitForDeferred(getThing())
        yield x
        x = x.getResult()

        self.assertEqual(x, "hi")

        ow = waitForDeferred(getOwie())
        yield ow
        try:
            ow.getResult()
        except ZeroDivisionError, e:
            self.assertEqual(str(e), 'OMG')
        yield "WOOSH"
        return

Example 11

Project: mythbox Source File: test_manhole.py
    def wfd(self, d):
        return defer.waitForDeferred(d)

Example 12

Project: mythbox Source File: test_defgen.py
Function: genbuggy
    def _genBuggy(self):
        yield waitForDeferred(getThing())
        1/0

Example 13

Project: ccs-calendarserver Source File: fileop.py
def copy(source_filepath, destination_filepath, destination_uri, depth):
    """
    Perform a X{COPY} from the given source and destination filepaths.
    This will perform a X{DELETE} on the destination if necessary; the caller
    should check and handle the X{overwrite} header before calling L{copy} (as
    in L{COPYMOVE.prepareForCopy}).
    @param source_filepath: a L{FilePath} for the file to copy from.
    @param destination_filepath: a L{FilePath} for the file to copy to.
    @param destination_uri: the URI of the destination resource.
    @param depth: the recursion X{Depth} for the X{COPY} operation, which must
        be one of "0", "1", or "infinity".
    @raise HTTPError: (containing a response with a status code of
        L{responsecode.BAD_REQUEST}) if C{depth} is not "0", "1" or "infinity".
    @raise HTTPError: (containing an appropriate response) if the operation
        fails.  If C{source_filepath} is a directory, the response will be a
        L{MultiStatusResponse}.
    @return: a deferred response with a status code of L{responsecode.CREATED}
        if the destination already exists, or L{responsecode.NO_CONTENT} if the
        destination was created by the X{COPY} operation.
    """
    if source_filepath.isfile():
        #
        # Copy the file
        #
        log.info("Copying file %s to %s" % (source_filepath.path, destination_filepath.path))

        try:
            source_file = source_filepath.open()
        except:
            raise HTTPError(statusForFailure(
                Failure(),
                "opening file for reading: %s" % (source_filepath.path,)
            ))

        source_stream = FileStream(source_file)
        response = waitForDeferred(put(source_stream, destination_filepath, destination_uri))
        yield response
        try:
            response = response.getResult()
        finally:
            source_stream.close()
            source_file.close()
        checkResponse(response, "put", responsecode.NO_CONTENT, responsecode.CREATED)
        yield response
        return

    elif source_filepath.isdir():
        if destination_filepath.exists():
            #
            # Delete the destination
            #
            response = waitForDeferred(delete(destination_uri, destination_filepath))
            yield response
            response = response.getResult()
            checkResponse(response, "delete", responsecode.NO_CONTENT)
            success_code = responsecode.NO_CONTENT
        else:
            success_code = responsecode.CREATED

        #
        # Copy the directory
        #
        log.info("Copying directory %s to %s" % (source_filepath.path, destination_filepath.path))

        source_basename = source_filepath.path
        destination_basename = destination_filepath.path

        errors = ResponseQueue(source_basename, "COPY", success_code)

        if destination_filepath.parent().isdir():
            if os.path.islink(source_basename):
                link_destination = os.readlink(source_basename)
                if link_destination[0] != os.path.sep:
                    link_destination = os.path.join(source_basename, link_destination)
                try:
                    os.symlink(destination_basename, link_destination)
                except:
                    errors.add(source_basename, Failure())
            else:
                try:
                    os.mkdir(destination_basename)
                except:
                    raise HTTPError(statusForFailure(
                        Failure(),
                        "creating directory %s" % (destination_basename,)
                    ))

                if depth == "0":
                    yield success_code
                    return
        else:
            raise HTTPError(StatusResponse(
                responsecode.CONFLICT,
                "Parent collection for destination %s does not exist" % (destination_uri,)
            ))

        #
        # Recursive copy
        #
        # FIXME: When we report errors, do we report them on the source URI
        # or on the destination URI?  We're using the source URI here.
        #
        # FIXME: defer the walk?

        source_basename_len = len(source_basename)

        def paths(basepath, subpath):
            source_path = os.path.join(basepath, subpath)
            assert source_path.startswith(source_basename)
            destination_path = os.path.join(destination_basename, source_path[source_basename_len + 1:])
            return source_path, destination_path

        for dir, subdirs, files in os.walk(source_filepath.path, topdown=True):
            for filename in files:
                source_path, destination_path = paths(dir, filename)
                if not os.path.isdir(os.path.dirname(destination_path)):
                    errors.add(source_path, responsecode.NOT_FOUND)
                else:
                    response = waitForDeferred(copy(FilePath(source_path), FilePath(destination_path), destination_uri, depth))
                    yield response
                    response = response.getResult()
                    checkResponse(response, "copy", responsecode.CREATED, responsecode.NO_CONTENT)

            for subdir in subdirs:
                source_path, destination_path = paths(dir, subdir)
                log.info("Copying directory %s to %s" % (source_path, destination_path))

                if not os.path.isdir(os.path.dirname(destination_path)):
                    errors.add(source_path, responsecode.CONFLICT)
                else:
                    if os.path.islink(source_path):
                        link_destination = os.readlink(source_path)
                        if link_destination[0] != os.path.sep:
                            link_destination = os.path.join(source_path, link_destination)
                        try:
                            os.symlink(destination_path, link_destination)
                        except:
                            errors.add(source_path, Failure())
                    else:
                        try:
                            os.mkdir(destination_path)
                        except:
                            errors.add(source_path, Failure())

        yield errors.response()
        return
    else:
        log.error("Unable to COPY to non-file: %s" % (source_filepath.path,))
        raise HTTPError(StatusResponse(
            responsecode.FORBIDDEN,
            "The requested resource exists but is not backed by a regular file."
        ))

Example 14

Project: ccs-calendarserver Source File: fileop.py
def move(source_filepath, source_uri, destination_filepath, destination_uri, depth):
    """
    Perform a X{MOVE} from the given source and destination filepaths.
    This will perform a X{DELETE} on the destination if necessary; the caller
    should check and handle the X{overwrite} header before calling L{copy} (as
    in L{COPYMOVE.prepareForCopy}).
    Following the X{DELETE}, this will attempt an atomic filesystem move.  If
    that fails, a X{COPY} operation followed by a X{DELETE} on the source will
    be attempted instead.
    @param source_filepath: a L{FilePath} for the file to copy from.
    @param destination_filepath: a L{FilePath} for the file to copy to.
    @param destination_uri: the URI of the destination resource.
    @param depth: the recursion X{Depth} for the X{MOVE} operation, which must
        be "infinity".
    @raise HTTPError: (containing a response with a status code of
        L{responsecode.BAD_REQUEST}) if C{depth} is not "infinity".
    @raise HTTPError: (containing an appropriate response) if the operation
        fails.  If C{source_filepath} is a directory, the response will be a
        L{MultiStatusResponse}.
    @return: a deferred response with a status code of L{responsecode.CREATED}
        if the destination already exists, or L{responsecode.NO_CONTENT} if the
        destination was created by the X{MOVE} operation.
    """
    log.info("Moving %s to %s" % (source_filepath.path, destination_filepath.path))

    #
    # Choose a success status
    #
    if destination_filepath.exists():
        #
        # Delete the destination
        #
        response = waitForDeferred(delete(destination_uri, destination_filepath))
        yield response
        response = response.getResult()
        checkResponse(response, "delete", responsecode.NO_CONTENT)

        success_code = responsecode.NO_CONTENT
    else:
        success_code = responsecode.CREATED

    #
    # See if rename (which is atomic, and fast) works
    #
    try:
        os.rename(source_filepath.path, destination_filepath.path)
    except OSError:
        pass
    else:
        # Remove stat info from source filepath since we moved it
        source_filepath.changed()
        yield success_code
        return

    #
    # Do a copy, then delete the source
    #

    response = waitForDeferred(copy(source_filepath, destination_filepath, destination_uri, depth))
    yield response
    response = response.getResult()
    checkResponse(response, "copy", responsecode.CREATED, responsecode.NO_CONTENT)

    response = waitForDeferred(delete(source_uri, source_filepath))
    yield response
    response = response.getResult()
    checkResponse(response, "delete", responsecode.NO_CONTENT)

    yield success_code

Example 15

Project: ccs-calendarserver Source File: fileop.py
def put(stream, filepath, uri=None):
    """
    Perform a PUT of the given data stream into the given filepath.
    @param stream: the stream to write to the destination.
    @param filepath: the L{FilePath} of the destination file.
    @param uri: the URI of the destination resource.
        If the destination exists, if C{uri} is not C{None}, perform a
        X{DELETE} operation on the destination, but if C{uri} is C{None},
        delete the destination directly.
        Note that whether a L{put} deletes the destination directly vs.
        performing a X{DELETE} on the destination affects the response returned
        in the event of an error during deletion.  Specifically, X{DELETE}
        on collections must return a L{MultiStatusResponse} under certain
        circuemstances, whereas X{PUT} isn't required to do so.  Therefore,
        if the caller expects X{DELETE} semantics, it must provide a valid
        C{uri}.
    @raise HTTPError: (containing an appropriate response) if the operation
        fails.
    @return: a deferred response with a status code of L{responsecode.CREATED}
        if the destination already exists, or L{responsecode.NO_CONTENT} if the
        destination was created by the X{PUT} operation.
    """
    log.info("Writing to file %s" % (filepath.path,))

    if filepath.exists():
        if uri is None:
            try:
                if filepath.isdir():
                    rmdir(filepath.path)
                else:
                    os.remove(filepath.path)
            except:
                raise HTTPError(statusForFailure(
                    Failure(),
                    "writing to file: %s" % (filepath.path,)
                ))
        else:
            response = waitForDeferred(delete(uri, filepath))
            yield response
            response = response.getResult()
            checkResponse(response, "delete", responsecode.NO_CONTENT)

        success_code = responsecode.NO_CONTENT
    else:
        success_code = responsecode.CREATED

    #
    # Write the contents of the request stream to resource's file
    #

    try:
        resource_file = filepath.open("w")
    except:
        raise HTTPError(statusForFailure(
            Failure(),
            "opening file for writing: %s" % (filepath.path,)
        ))

    try:
        x = waitForDeferred(readIntoFile(stream, resource_file))
        yield x
        x.getResult()
    except:
        raise HTTPError(statusForFailure(
            Failure(),
            "writing to file: %s" % (filepath.path,)
        ))

    # Remove stat info from filepath since we modified the backing file
    resource_file.close()
    filepath.changed()
    yield success_code

Example 16

Project: ccs-calendarserver Source File: acl.py
def http_ACL(self, request):
    """
    Respond to a ACL request. (RFC 3744, section 8.1)
    """
    if not self.exists():
        log.error("File not found: %s" % (self,))
        yield responsecode.NOT_FOUND
        return

    #
    # Check authentication and access controls
    #
    x = waitForDeferred(self.authorize(request, (davxml.WriteACL(),)))
    yield x
    x.getResult()

    #
    # Read request body
    #
    doc = waitForDeferred(davXMLFromStream(request.stream))
    yield doc
    try:
        doc = doc.getResult()
    except ValueError, e:
        log.error("Error while handling ACL body: %s" % (e,))
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, str(e)))

    #
    # Set properties
    #
    if doc is None:
        error = "Request XML body is required."
        log.error("Error: {err}", err=error)
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, error))

    #
    # Parse request
    #
    acl = doc.root_element
    if not isinstance(acl, davxml.ACL):
        error = ("Request XML body must be an acl element."
                 % (davxml.PropertyUpdate.sname(),))
        log.error("Error: {err}", err=error)
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, error))

    #
    # Do ACL merger
    #
    result = waitForDeferred(self.mergeAccessControlList(acl, request))
    yield result
    result = result.getResult()

    #
    # Return response
    #
    if result is None:
        yield responsecode.OK
    else:
        yield ErrorResponse(responsecode.FORBIDDEN, result)

Example 17

Project: ccs-calendarserver Source File: copymove.py
Function: http_copy
def http_COPY(self, request):
    """
    Respond to a COPY request. (RFC 2518, section 8.8)
    """
    r = waitForDeferred(prepareForCopy(self, request))
    yield r
    r = r.getResult()

    destination, destination_uri, depth = r

    #
    # Check authentication and access controls
    #
    x = waitForDeferred(self.authorize(request, (davxml.Read(),), recurse=True))
    yield x
    x.getResult()

    if destination.exists():
        x = waitForDeferred(destination.authorize(
            request,
            (davxml.WriteContent(), davxml.WriteProperties()),
            recurse=True
        ))
        yield x
        x.getResult()
    else:
        destparent = waitForDeferred(request.locateResource(parentForURL(destination_uri)))
        yield destparent
        destparent = destparent.getResult()

        x = waitForDeferred(destparent.authorize(request, (davxml.Bind(),)))
        yield x
        x.getResult()

        # May need to add a location header
        addLocation(request, destination_uri)

    # x = waitForDeferred(copy(self.fp, destination.fp, destination_uri, depth))
    x = waitForDeferred(put_common.storeResource(request,
                                                 source=self,
                                                 source_uri=request.uri,
                                                 destination=destination,
                                                 destination_uri=destination_uri,
                                                 deletesource=False,
                                                 depth=depth
                                                 ))
    yield x
    yield x.getResult()

Example 18

Project: ccs-calendarserver Source File: copymove.py
def http_MOVE(self, request):
    """
    Respond to a MOVE request. (RFC 2518, section 8.9)
    """
    r = waitForDeferred(prepareForCopy(self, request))
    yield r
    r = r.getResult()

    destination, destination_uri, depth = r

    #
    # Check authentication and access controls
    #
    parentURL = parentForURL(request.uri)
    parent = waitForDeferred(request.locateResource(parentURL))
    yield parent
    parent = parent.getResult()

    x = waitForDeferred(parent.authorize(request, (davxml.Unbind(),)))
    yield x
    x.getResult()

    if destination.exists():
        x = waitForDeferred(destination.authorize(
            request,
            (davxml.Bind(), davxml.Unbind()),
            recurse=True
        ))
        yield x
        x.getResult()
    else:
        destparentURL = parentForURL(destination_uri)
        destparent = waitForDeferred(request.locateResource(destparentURL))
        yield destparent
        destparent = destparent.getResult()

        x = waitForDeferred(destparent.authorize(request, (davxml.Bind(),)))
        yield x
        x.getResult()

        # May need to add a location header
        addLocation(request, destination_uri)

    #
    # RFC 2518, section 8.9 says that we must act as if the Depth header is set
    # to infinity, and that the client must omit the Depth header or set it to
    # infinity.
    #
    # This seems somewhat at odds with the notion that a bad request should be
    # rejected outright; if the client sends a bad depth header, the client is
    # broken, and section 8 suggests that a bad request should be rejected...
    #
    # Let's play it safe for now and ignore broken clients.
    #
    if self.isCollection() and depth != "infinity":
        msg = "Client sent illegal depth header value for MOVE: %s" % (depth,)
        log.error(msg)
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, msg))

    # Lets optimise a move within the same directory to a new resource as a simple move
    # rather than using the full transaction based storeResource api. This allows simple
    # "rename" operations to work quickly.
    if (not destination.exists()) and destparent == parent:
        x = waitForDeferred(move(self.fp, request.uri, destination.fp, destination_uri, depth))
    else:
        x = waitForDeferred(put_common.storeResource(request,
                                                     source=self,
                                                     source_uri=request.uri,
                                                     destination=destination,
                                                     destination_uri=destination_uri,
                                                     deletesource=True,
                                                     depth=depth))
    yield x
    yield x.getResult()

Example 19

Project: ccs-calendarserver Source File: delete.py
def http_DELETE(self, request):
    """
    Respond to a DELETE request. (RFC 2518, section 8.6)
    """
    if not self.exists():
        log.error("File not found: %s" % (self,))
        raise HTTPError(responsecode.NOT_FOUND)

    depth = request.headers.getHeader("depth", "infinity")

    #
    # Check authentication and access controls
    #
    parent = waitForDeferred(request.locateResource(parentForURL(request.uri)))
    yield parent
    parent = parent.getResult()

    x = waitForDeferred(parent.authorize(request, (davxml.Unbind(),)))
    yield x
    x.getResult()

    x = waitForDeferred(deleteResource(request, self, request.uri, depth))
    yield x
    yield x.getResult()

Example 20

Project: ccs-calendarserver Source File: delete_common.py
def deleteResource(request, resource, resource_uri, depth="0"):
    """
    Handle a resource delete with proper quota etc updates
    """
    if not resource.exists():
        log.error("File not found: %s" % (resource,))
        raise HTTPError(responsecode.NOT_FOUND)

    # Do quota checks before we start deleting things
    myquota = waitForDeferred(resource.quota(request))
    yield myquota
    myquota = myquota.getResult()
    if myquota is not None:
        old_size = waitForDeferred(resource.quotaSize(request))
        yield old_size
        old_size = old_size.getResult()
    else:
        old_size = 0

    # Do delete
    x = waitForDeferred(delete(resource_uri, resource.fp, depth))
    yield x
    result = x.getResult()

    # Adjust quota
    if myquota is not None:
        d = waitForDeferred(resource.quotaSizeAdjust(request, -old_size))
        yield d
        d.getResult()

    yield result

Example 21

Project: ccs-calendarserver Source File: mkcol.py
def http_MKCOL(self, request):
    """
    Respond to a MKCOL request. (RFC 2518, section 8.3)
    """
    parent = waitForDeferred(request.locateResource(parentForURL(request.uri)))
    yield parent
    parent = parent.getResult()

    x = waitForDeferred(parent.authorize(request, (davxml.Bind(),)))
    yield x
    x.getResult()

    if self.exists():
        log.error("Attempt to create collection where file exists: %s"
                  % (self,))
        raise HTTPError(responsecode.NOT_ALLOWED)

    if not parent.isCollection():
        log.error("Attempt to create collection with non-collection parent: %s"
                  % (self,))
        raise HTTPError(StatusResponse(
            responsecode.CONFLICT,
            "Parent resource is not a collection."
        ))

    #
    # Read request body
    #
    x = waitForDeferred(noDataFromStream(request.stream))
    yield x
    try:
        x.getResult()
    except ValueError, e:
        log.error("Error while handling MKCOL body: %s" % (e,))
        raise HTTPError(responsecode.UNSUPPORTED_MEDIA_TYPE)

    response = waitForDeferred(mkcollection(self.fp))
    yield response
    yield response.getResult()

Example 22

Project: ccs-calendarserver Source File: propfind.py
def http_PROPFIND(self, request):
    """
    Respond to a PROPFIND request. (RFC 2518, section 8.1)
    """
    if not self.exists():
        log.error("File not found: %s" % (self,))
        raise HTTPError(responsecode.NOT_FOUND)

    #
    # Check authentication and access controls
    #
    x = waitForDeferred(self.authorize(request, (davxml.Read(),)))
    yield x
    x.getResult()

    #
    # Read request body
    #
    try:
        doc = waitForDeferred(davXMLFromStream(request.stream))
        yield doc
        doc = doc.getResult()
    except ValueError, e:
        log.error("Error while handling PROPFIND body: %s" % (e,))
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, str(e)))

    if doc is None:
        # No request body means get all properties.
        search_properties = "all"
    else:
        #
        # Parse request
        #
        find = doc.root_element
        if not isinstance(find, davxml.PropertyFind):
            error = ("Non-%s element in PROPFIND request body: %s"
                     % (davxml.PropertyFind.sname(), find))
            log.error("Error: {err}", err=error)
            raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, error))

        container = find.children[0]

        if isinstance(container, davxml.AllProperties):
            # Get all properties
            search_properties = "all"
        elif isinstance(container, davxml.PropertyName):
            # Get names only
            search_properties = "names"
        elif isinstance(container, davxml.PropertyContainer):
            properties = container.children
            search_properties = [(p.namespace, p.name) for p in properties]
        else:
            raise AssertionError("Unexpected element type in %s: %s"
                                 % (davxml.PropertyFind.sname(), container))

    #
    # Generate XML output stream
    #
    request_uri = request.uri
    depth = request.headers.getHeader("depth", "infinity")

    # By policy we will never allow a depth:infinity propfind
    if depth == "infinity":
        raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, davxml.PropfindFiniteDepth()))

    # Look for Prefer header first, then try Brief
    prefer = request.headers.getHeader("prefer", {})
    returnMinimal = any([key == "return" and value == "minimal" for key, value, _ignore_args in prefer])
    noRoot = any([key == "depth-noroot" and value is None for key, value, _ignore_args in prefer])
    if not returnMinimal:
        returnMinimal = request.headers.getHeader("brief", False)

    xml_responses = []

    # FIXME: take advantage of the new generative properties of findChildren

    my_url = normalizeURL(request_uri)
    if self.isCollection() and not my_url.endswith("/"):
        my_url += "/"

    # Do some optimisation of access control calculation by determining any inherited ACLs outside of
    # the child resource loop and supply those to the checkPrivileges on each child.
    filtered_aces = waitForDeferred(self.inheritedACEsforChildren(request))
    yield filtered_aces
    filtered_aces = filtered_aces.getResult()

    if depth in ("1", "infinity") and noRoot:
        resources = []
    else:
        resources = [(self, my_url)]

    d = self.findChildren(depth, request, lambda x, y: resources.append((x, y)), (davxml.Read(),), inherited_aces=filtered_aces)
    x = waitForDeferred(d)
    yield x
    x.getResult()

    for resource, uri in resources:

        if search_properties == "names":
            try:
                resource_properties = waitForDeferred(resource.listProperties(request))
                yield resource_properties
                resource_properties = resource_properties.getResult()
            except:
                log.error("Unable to get properties for resource %r" % (resource,))
                raise

            properties_by_status = {
                responsecode.OK: [propertyName(p) for p in resource_properties]
            }
        else:
            properties_by_status = {
                responsecode.OK: [],
                responsecode.NOT_FOUND: [],
            }

            if search_properties == "all":
                properties_to_enumerate = waitForDeferred(resource.listAllprop(request))
                yield properties_to_enumerate
                properties_to_enumerate = properties_to_enumerate.getResult()
            else:
                properties_to_enumerate = search_properties

            for property in properties_to_enumerate:
                if hasattr(resource, "hasProperty"):
                    has = waitForDeferred(resource.hasProperty(property, request))
                    yield has
                    has = has.getResult()
                else:
                    has = False
                if has:
                    try:
                        resource_property = waitForDeferred(resource.readProperty(property, request))
                        yield resource_property
                        resource_property = resource_property.getResult()
                    except:
                        f = Failure()
                        status = statusForFailure(f, "getting property: %s" % (property,))
                        if status not in properties_by_status:
                            properties_by_status[status] = []
                        if not returnMinimal or status != responsecode.NOT_FOUND:
                            properties_by_status[status].append(propertyName(property))
                    else:
                        if resource_property is not None:
                            properties_by_status[responsecode.OK].append(resource_property)
                        elif not returnMinimal:
                            properties_by_status[responsecode.NOT_FOUND].append(propertyName(property))
                elif not returnMinimal:
                    properties_by_status[responsecode.NOT_FOUND].append(propertyName(property))

        propstats = []

        for status in properties_by_status:
            properties = properties_by_status[status]
            if not properties:
                continue

            xml_status = davxml.Status.fromResponseCode(status)
            xml_container = davxml.PropertyContainer(*properties)
            xml_propstat = davxml.PropertyStatus(xml_container, xml_status)

            propstats.append(xml_propstat)

        # Always need to have at least one propstat present (required by Prefer header behavior)
        if len(propstats) == 0:
            propstats.append(davxml.PropertyStatus(
                davxml.PropertyContainer(),
                davxml.Status.fromResponseCode(responsecode.OK)
            ))

        xml_resource = davxml.HRef(uri)
        xml_response = davxml.PropertyStatusResponse(xml_resource, *propstats)

        xml_responses.append(xml_response)

    #
    # Return response
    #
    yield MultiStatusResponse(xml_responses)

Example 23

Project: ccs-calendarserver Source File: proppatch.py
def http_PROPPATCH(self, request):
    """
    Respond to a PROPPATCH request. (RFC 2518, section 8.2)
    """
    if not self.exists():
        log.error("File not found: %s" % (self,))
        raise HTTPError(responsecode.NOT_FOUND)

    x = waitForDeferred(self.authorize(request, (davxml.WriteProperties(),)))
    yield x
    x.getResult()

    #
    # Read request body
    #
    try:
        doc = waitForDeferred(davXMLFromStream(request.stream))
        yield doc
        doc = doc.getResult()
    except ValueError, e:
        log.error("Error while handling PROPPATCH body: %s" % (e,))
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, str(e)))

    if doc is None:
        error = "Request XML body is required."
        log.error("Error: {err}", error)
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, error))

    #
    # Parse request
    #
    update = doc.root_element
    if not isinstance(update, davxml.PropertyUpdate):
        error = ("Request XML body must be a propertyupdate element."
                 % (davxml.PropertyUpdate.sname(),))
        log.error("Error: {err}", error)
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, error))

    responses = PropertyStatusResponseQueue("PROPPATCH", request.uri, responsecode.NO_CONTENT)
    undoActions = []
    gotError = False

    # Look for Prefer header
    prefer = request.headers.getHeader("prefer", {})
    returnMinimal = any([key == "return" and value == "minimal" for key, value, _ignore_args in prefer])

    try:
        #
        # Update properties
        #
        for setOrRemove in update.children:
            assert len(setOrRemove.children) == 1

            container = setOrRemove.children[0]

            assert isinstance(container, davxml.PropertyContainer)

            properties = container.children

            def do(action, property, removing=False):
                """
                Perform action(property, request) while maintaining an
                undo queue.
                """
                has = waitForDeferred(self.hasProperty(property, request))
                yield has
                has = has.getResult()

                if has:
                    oldProperty = waitForDeferred(self.readProperty(property, request))
                    yield oldProperty
                    oldProperty = oldProperty.getResult()

                    def undo():
                        return self.writeProperty(oldProperty, request)
                else:
                    def undo():
                        return self.removeProperty(property, request)

                try:
                    x = waitForDeferred(action(property, request))
                    yield x
                    x.getResult()
                except KeyError, e:
                    # Removing a non-existent property is OK according to WebDAV
                    if removing:
                        responses.add(responsecode.OK, property)
                        yield True
                        return
                    else:
                        # Convert KeyError exception into HTTPError
                        responses.add(
                            Failure(exc_value=HTTPError(StatusResponse(responsecode.FORBIDDEN, str(e)))),
                            property
                        )
                        yield False
                        return
                except:
                    responses.add(Failure(), property)
                    yield False
                    return
                else:
                    responses.add(responsecode.OK, property)

                    # Only add undo action for those that succeed because those that fail will not have changed
                    undoActions.append(undo)

                    yield True
                    return

            do = deferredGenerator(do)

            if isinstance(setOrRemove, davxml.Set):
                for property in properties:
                    ok = waitForDeferred(do(self.writeProperty, property))
                    yield ok
                    ok = ok.getResult()
                    if not ok:
                        gotError = True
            elif isinstance(setOrRemove, davxml.Remove):
                for property in properties:
                    ok = waitForDeferred(do(self.removeProperty, property, True))
                    yield ok
                    ok = ok.getResult()
                    if not ok:
                        gotError = True
            else:
                raise AssertionError("Unknown child of PropertyUpdate: %s" % (setOrRemove,))
    except:
        #
        # If there is an error, we have to back out whatever we have
        # operations we have done because PROPPATCH is an
        # all-or-nothing request.
        # We handle the first one here, and then re-raise to handle the
        # rest in the containing scope.
        #
        for action in undoActions:
            x = waitForDeferred(action())
            yield x
            x.getResult()
        raise

    #
    # If we had an error we need to undo any changes that did succeed and change status of
    # those to 424 Failed Dependency.
    #
    if gotError:
        for action in undoActions:
            x = waitForDeferred(action())
            yield x
            x.getResult()
        responses.error()

    #
    # Return response - use 200 if Prefer:return=minimal set and no errors
    #
    if returnMinimal and not gotError:
        yield responsecode.OK
    else:
        yield MultiStatusResponse([responses.response()])

Example 24

Project: ccs-calendarserver Source File: prop_common.py
def responseForHref(request, responses, href, resource, propertiesForResource, propertyreq):

    if propertiesForResource is not None:
        properties_by_status = waitForDeferred(propertiesForResource(request, propertyreq, resource))
        yield properties_by_status
        properties_by_status = properties_by_status.getResult()

        propstats = []

        for status in properties_by_status:
            properties = properties_by_status[status]
            if properties:
                xml_status = element.Status.fromResponseCode(status)
                xml_container = element.PropertyContainer(*properties)
                xml_propstat = element.PropertyStatus(xml_container, xml_status)

                propstats.append(xml_propstat)

        if propstats:
            responses.append(element.PropertyStatusResponse(href, *propstats))

    else:
        responses.append(
            element.StatusResponse(
                href,
                element.Status.fromResponseCode(responsecode.OK),
            )
        )

Example 25

Project: ccs-calendarserver Source File: prop_common.py
def _namedPropertiesForResource(request, props, resource):
    """
    Return the specified properties on the specified resource.
    @param request: the L{IRequest} for the current request.
    @param props: a list of property elements or qname tuples for the properties of interest.
    @param resource: the L{DAVFile} for the targetted resource.
    @return: a map of OK and NOT FOUND property values.
    """
    properties_by_status = {
        responsecode.OK: [],
        responsecode.NOT_FOUND: [],
    }

    for property in props:
        if isinstance(property, element.WebDAVElement):
            qname = property.qname()
        else:
            qname = property

        props = waitForDeferred(resource.listProperties(request))
        yield props
        props = props.getResult()
        if qname in props:
            try:
                prop = waitForDeferred(resource.readProperty(qname, request))
                yield prop
                prop = prop.getResult()
                properties_by_status[responsecode.OK].append(prop)
            except:
                f = Failure()
                status = statusForFailure(f, "getting property: %s" % (qname,))
                if status != responsecode.NOT_FOUND:
                    log.error("Error reading property %r for resource %s: %s" %
                              (qname, request.uri, f.value))
                if status not in properties_by_status:
                    properties_by_status[status] = []
                properties_by_status[status].append(propertyName(qname))
        else:
            properties_by_status[responsecode.NOT_FOUND].append(propertyName(qname))

    yield properties_by_status

Example 26

Project: ccs-calendarserver Source File: put.py
def preconditions_PUT(self, request):
    #
    # Check authentication and access controls
    #
    if self.exists():
        x = waitForDeferred(self.authorize(request, (davxml.WriteContent(),)))
        yield x
        x.getResult()
    else:
        parent = waitForDeferred(request.locateResource(parentForURL(request.uri)))
        yield parent
        parent = parent.getResult()

        if not parent.exists():
            raise HTTPError(
                StatusResponse(
                    responsecode.CONFLICT,
                    "cannot PUT to non-existent parent"))
        x = waitForDeferred(parent.authorize(request, (davxml.Bind(),)))
        yield x
        x.getResult()

    #
    # HTTP/1.1 (RFC 2068, section 9.6) requires that we respond with a Not
    # Implemented error if we get a Content-* header which we don't
    # recognize and handle properly.
    #
    for header, _ignore_value in request.headers.getAllRawHeaders():
        if header.startswith("Content-") and header not in (
            # "Content-Base",     # Doesn't make sense in PUT?
            # "Content-Encoding", # Requires that we decode it?
            "Content-Language",
            "Content-Length",
            # "Content-Location", # Doesn't make sense in PUT?
            "Content-MD5",
            # "Content-Range",    # FIXME: Need to implement this
            "Content-Type",
        ):
            log.error("Client sent unrecognized content header in PUT request: %s"
                      % (header,))
            raise HTTPError(StatusResponse(
                responsecode.NOT_IMPLEMENTED,
                "Unrecognized content header %r in request." % (header,)
            ))

Example 27

Project: ccs-calendarserver Source File: put_common.py
def storeResource(
    request,
    source=None, source_uri=None, data=None,
    destination=None, destination_uri=None,
    deletesource=False,
    depth="0"
):
    """
    Function that does common PUT/COPY/MOVE behaviour.

    @param request:           the L{txweb2.server.Request} for the current HTTP request.
    @param source:            the L{DAVFile} for the source resource to copy from, or None if source data
                              is to be read from the request.
    @param source_uri:        the URI for the source resource.
    @param data:              a C{str} to copy data from instead of the request stream.
    @param destination:       the L{DAVFile} for the destination resource to copy into.
    @param destination_uri:   the URI for the destination resource.
    @param deletesource:      True if the source resource is to be deleted on successful completion, False otherwise.
    @param depth:             a C{str} containing the COPY/MOVE Depth header value.
    @return:                  status response.
    """

    try:
        assert request is not None and destination is not None and destination_uri is not None
        assert (source is None) or (source is not None and source_uri is not None)
        assert not deletesource or (deletesource and source is not None)
    except AssertionError:
        log.error("Invalid arguments to storeResource():")
        log.error("request=%s\n" % (request,))
        log.error("source=%s\n" % (source,))
        log.error("source_uri=%s\n" % (source_uri,))
        log.error("data=%s\n" % (data,))
        log.error("destination=%s\n" % (destination,))
        log.error("destination_uri=%s\n" % (destination_uri,))
        log.error("deletesource=%s\n" % (deletesource,))
        log.error("depth=%s\n" % (depth,))
        raise

    class RollbackState(object):
        """
        This class encapsulates the state needed to rollback the entire PUT/COPY/MOVE
        transaction, leaving the server state the same as it was before the request was
        processed. The DoRollback method will actually execute the rollback operations.
        """

        def __init__(self):
            self.active = True
            self.source_copy = None
            self.destination_copy = None
            self.destination_created = False
            self.source_deleted = False

        def Rollback(self):
            """
            Rollback the server state. Do not allow this to raise another exception. If
            rollback fails then we are going to be left in an awkward state that will need
            to be cleaned up eventually.
            """
            if self.active:
                self.active = False
                log.error("Rollback: rollback")
                try:
                    if self.source_copy and self.source_deleted:
                        self.source_copy.moveTo(source.fp)
                        log.error("Rollback: source restored %s to %s" % (self.source_copy.path, source.fp.path))
                        self.source_copy = None
                        self.source_deleted = False
                    if self.destination_copy:
                        destination.fp.remove()
                        log.error("Rollback: destination restored %s to %s" % (self.destination_copy.path, destination.fp.path))
                        self.destination_copy.moveTo(destination.fp)
                        self.destination_copy = None
                    elif self.destination_created:
                        destination.fp.remove()
                        log.error("Rollback: destination removed %s" % (destination.fp.path,))
                        self.destination_created = False
                except:
                    log.error("Rollback: exception caught and not handled: %s" % Failure())

        def Commit(self):
            """
            Commit the resource changes by wiping the rollback state.
            """
            if self.active:
                log.error("Rollback: commit")
                self.active = False
                if self.source_copy:
                    self.source_copy.remove()
                    log.error("Rollback: removed source backup %s" % (self.source_copy.path,))
                    self.source_copy = None
                if self.destination_copy:
                    self.destination_copy.remove()
                    log.error("Rollback: removed destination backup %s" % (self.destination_copy.path,))
                    self.destination_copy = None
                self.destination_created = False
                self.source_deleted = False

    rollback = RollbackState()

    try:
        """
        Handle validation operations here.
        """

        """
        Handle rollback setup here.
        """

        # Do quota checks on destination and source before we start messing with adding other files
        destquota = waitForDeferred(destination.quota(request))
        yield destquota
        destquota = destquota.getResult()
        if destquota is not None and destination.exists():
            old_dest_size = waitForDeferred(destination.quotaSize(request))
            yield old_dest_size
            old_dest_size = old_dest_size.getResult()
        else:
            old_dest_size = 0

        if source is not None:
            sourcequota = waitForDeferred(source.quota(request))
            yield sourcequota
            sourcequota = sourcequota.getResult()
            if sourcequota is not None and source.exists():
                old_source_size = waitForDeferred(source.quotaSize(request))
                yield old_source_size
                old_source_size = old_source_size.getResult()
            else:
                old_source_size = 0
        else:
            sourcequota = None
            old_source_size = 0

        # We may need to restore the original resource data if the PUT/COPY/MOVE fails,
        # so rename the original file in case we need to rollback.
        overwrite = destination.exists()
        if overwrite:
            rollback.destination_copy = FilePath(destination.fp.path)
            rollback.destination_copy.path += ".rollback"
            destination.fp.copyTo(rollback.destination_copy)
        else:
            rollback.destination_created = True

        if deletesource:
            rollback.source_copy = FilePath(source.fp.path)
            rollback.source_copy.path += ".rollback"
            source.fp.copyTo(rollback.source_copy)

        """
        Handle actual store operations here.
        """

        # Do put or copy based on whether source exists
        if source is not None:
            response = maybeDeferred(copy, source.fp, destination.fp, destination_uri, depth)
        else:
            datastream = request.stream
            if data is not None:
                datastream = MemoryStream(data)
            md5 = MD5Stream(datastream)
            response = maybeDeferred(put, md5, destination.fp)

        response = waitForDeferred(response)
        yield response
        response = response.getResult()

        # Update the MD5 value on the resource
        if source is not None:
            # Copy MD5 value from source to destination
            if source.hasDeadProperty(TwistedGETContentMD5):
                md5 = source.readDeadProperty(TwistedGETContentMD5)
                destination.writeDeadProperty(md5)
        else:
            # Finish MD5 calc and write dead property
            md5.close()
            md5 = md5.getMD5()
            destination.writeDeadProperty(TwistedGETContentMD5.fromString(md5))

        # Update the content-type value on the resource if it is not been copied or moved
        if source is None:
            content_type = request.headers.getHeader("content-type")
            if content_type is not None:
                destination.writeDeadProperty(davxml.GETContentType.fromString(generateContentType(content_type)))

        response = IResponse(response)

        # Do quota check on destination
        if destquota is not None:
            # Get size of new/old resources
            new_dest_size = waitForDeferred(destination.quotaSize(request))
            yield new_dest_size
            new_dest_size = new_dest_size.getResult()
            diff_size = new_dest_size - old_dest_size
            if diff_size >= destquota[0]:
                log.error("Over quota: available %d, need %d" % (destquota[0], diff_size))
                raise HTTPError(ErrorResponse(
                    responsecode.INSUFFICIENT_STORAGE_SPACE,
                    (dav_namespace, "quota-not-exceeded")
                ))
            d = waitForDeferred(destination.quotaSizeAdjust(request, diff_size))
            yield d
            d.getResult()

        if deletesource:
            # Delete the source resource
            if sourcequota is not None:
                delete_size = 0 - old_source_size
                d = waitForDeferred(source.quotaSizeAdjust(request, delete_size))
                yield d
                d.getResult()

            delete(source_uri, source.fp, depth)
            rollback.source_deleted = True

        # Can now commit changes and forget the rollback details
        rollback.Commit()

        yield response
        return

    except:
        # Roll back changes to original server state. Note this may do nothing
        # if the rollback has already ocurred or changes already committed.
        rollback.Rollback()
        raise

Example 28

Project: ccs-calendarserver Source File: report.py
def http_REPORT(self, request):
    """
    Respond to a REPORT request. (RFC 3253, section 3.6)
    """
    if not self.exists():
        log.error("File not found: %s" % (self,))
        raise HTTPError(responsecode.NOT_FOUND)

    #
    # Check authentication and access controls
    #
    x = waitForDeferred(self.authorize(request, (davxml.Read(),)))
    yield x
    x.getResult()

    #
    # Read request body
    #
    try:
        doc = waitForDeferred(davXMLFromStream(request.stream))
        yield doc
        doc = doc.getResult()
    except ValueError, e:
        log.error("Error while handling REPORT body: %s" % (e,))
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, str(e)))

    if doc is None:
        raise HTTPError(StatusResponse(
            responsecode.BAD_REQUEST,
            "REPORT request body may not be empty"
        ))

    #
    # Parse request
    #
    namespace = doc.root_element.namespace
    name = doc.root_element.name

    ok = string.ascii_letters + string.digits + "_"

    def to_method(s):
        out = []
        for c in s:
            if c in ok:
                out.append(c)
            else:
                out.append("_")
        return "report_" + "".join(out)

    if namespace:
        method_name = to_method("_".join((namespace, name)))

        if namespace == davxml.dav_namespace:
            request.submethod = "DAV:" + name
        else:
            request.submethod = encodeXMLName(namespace, name)
    else:
        method_name = to_method(name)

        request.submethod = name

    try:
        method = getattr(self, method_name)

        # Also double-check via supported-reports property
        reports = self.supportedReports()
        test = lookupElement((namespace, name))
        if not test:
            raise AttributeError()
        test = davxml.Report(test())
        if test not in reports:
            raise AttributeError()
    except AttributeError:
        #
        # Requested report is not supported.
        #
        log.error("Unsupported REPORT %s for resource %s (no method %s)"
                  % (encodeXMLName(namespace, name), self, method_name))

        raise HTTPError(ErrorResponse(
            responsecode.FORBIDDEN,
            davxml.SupportedReport()
        ))

    d = waitForDeferred(method(request, doc.root_element))
    yield d
    yield d.getResult()

Example 29

Project: ccs-calendarserver Source File: report_acl_principal_prop_set.py
def report_DAV__acl_principal_prop_set(self, request, acl_prinicpal_prop_set):
    """
    Generate an acl-prinicpal-prop-set REPORT. (RFC 3744, section 9.2)
    """
    # Verify root element
    if not isinstance(acl_prinicpal_prop_set, davxml.ACLPrincipalPropSet):
        raise ValueError("%s expected as root element, not %s."
                         % (davxml.ACLPrincipalPropSet.sname(), acl_prinicpal_prop_set.sname()))

    # Depth must be "0"
    depth = request.headers.getHeader("depth", "0")
    if depth != "0":
        log.error("Error in prinicpal-prop-set REPORT, Depth set to %s" % (depth,))
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, "Depth %s not allowed" % (depth,)))

    #
    # Check authentication and access controls
    #
    x = waitForDeferred(self.authorize(request, (davxml.ReadACL(),)))
    yield x
    x.getResult()

    # Get a single DAV:prop element from the REPORT request body
    propertiesForResource = None
    propElement = None
    for child in acl_prinicpal_prop_set.children:
        if child.qname() == ("DAV:", "prop"):
            if propertiesForResource is not None:
                log.error("Only one DAV:prop element allowed")
                raise HTTPError(StatusResponse(
                    responsecode.BAD_REQUEST,
                    "Only one DAV:prop element allowed"
                ))
            propertiesForResource = prop_common.propertyListForResource
            propElement = child

    if propertiesForResource is None:
        log.error("Error in acl-principal-prop-set REPORT, no DAV:prop element")
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, "No DAV:prop element"))

    # Enumerate principals on ACL in current resource
    principals = []

    acl = waitForDeferred(self.accessControlList(request))
    yield acl
    acl = acl.getResult()

    for ace in acl.children:
        resolved = waitForDeferred(self.resolvePrincipal(ace.principal.children[0], request))
        yield resolved
        resolved = resolved.getResult()
        if resolved is not None and resolved not in principals:
            principals.append(resolved)

    # Run report for each referenced principal
    try:
        responses = []
        matchcount = 0
        for principal in principals:
            # Check size of results is within limit
            matchcount += 1
            if matchcount > max_number_of_matches:
                raise NumberOfMatchesWithinLimits(max_number_of_matches)

            resource = waitForDeferred(request.locateResource(str(principal)))
            yield resource
            resource = resource.getResult()

            if resource is not None:
                #
                # Check authentication and access controls
                #
                x = waitForDeferred(resource.authorize(request, (davxml.Read(),)))
                yield x
                try:
                    x.getResult()
                except HTTPError:
                    responses.append(davxml.StatusResponse(
                        principal,
                        davxml.Status.fromResponseCode(responsecode.FORBIDDEN)
                    ))
                else:
                    d = waitForDeferred(prop_common.responseForHref(
                        request,
                        responses,
                        principal,
                        resource,
                        propertiesForResource,
                        propElement
                    ))
                    yield d
                    d.getResult()
            else:
                log.error("Requested principal resource not found: %s" % (str(principal),))
                responses.append(davxml.StatusResponse(
                    principal,
                    davxml.Status.fromResponseCode(responsecode.NOT_FOUND)
                ))

    except NumberOfMatchesWithinLimits:
        log.error("Too many matching components")
        raise HTTPError(ErrorResponse(
            responsecode.FORBIDDEN,
            davxml.NumberOfMatchesWithinLimits()
        ))

    yield MultiStatusResponse(responses)

Example 30

Project: ccs-calendarserver Source File: report_principal_match.py
def report_DAV__principal_match(self, request, principal_match):
    """
    Generate a principal-match REPORT. (RFC 3744, section 9.3)
    """
    # Verify root element
    if not isinstance(principal_match, element.PrincipalMatch):
        raise ValueError("%s expected as root element, not %s."
                         % (element.PrincipalMatch.sname(), principal_match.sname()))

    # Only handle Depth: 0
    depth = request.headers.getHeader("depth", "0")
    if depth != "0":
        log.error("Non-zero depth is not allowed: %s" % (depth,))
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, "Depth %s not allowed" % (depth,)))

    # Get a single DAV:prop element from the REPORT request body
    propertiesForResource = None
    propElement = None
    principalPropElement = None
    lookForPrincipals = True

    for child in principal_match.children:
        if child.qname() == (dav_namespace, "prop"):
            propertiesForResource = prop_common.propertyListForResource
            propElement = child

        elif child.qname() == (dav_namespace, "self"):
            lookForPrincipals = True

        elif child.qname() == (dav_namespace, "principal-property"):
            # Must have one and only one property in this element
            if len(child.children) != 1:
                log.error("Wrong number of properties in DAV:principal-property: %s"
                          % (len(child.children),))
                raise HTTPError(StatusResponse(
                    responsecode.BAD_REQUEST,
                    "DAV:principal-property must contain exactly one property"
                ))

            lookForPrincipals = False
            principalPropElement = child.children[0]

    # Run report for each referenced principal
    try:
        responses = []
        matchcount = 0

        myPrincipalURL = self.currentPrincipal(request).children[0]

        if lookForPrincipals:

            # Find the set of principals that represent "self".

            # First add "self"
            principal = waitForDeferred(request.locateResource(str(myPrincipalURL)))
            yield principal
            principal = principal.getResult()
            selfItems = [principal, ]

            # Get group memberships for "self" and add each of those
            d = waitForDeferred(principal.groupMemberships())
            yield d
            memberships = d.getResult()
            selfItems.extend(memberships)

            # Now add each principal found to the response provided the principal resource is a child of
            # the current resource.
            for principal in selfItems:
                # Get all the URIs that point to the principal resource
                # FIXME: making the assumption that the principalURL() is the URL of the resource we found
                principal_uris = [principal.principalURL()]
                principal_uris.extend(principal.alternateURIs())

                # Compare each one to the request URI and return at most one that matches
                for uri in principal_uris:
                    if uri.startswith(request.uri):
                        # Check size of results is within limit
                        matchcount += 1
                        if matchcount > max_number_of_matches:
                            raise NumberOfMatchesWithinLimits(max_number_of_matches)

                        d = waitForDeferred(prop_common.responseForHref(
                            request,
                            responses,
                            element.HRef.fromString(uri),
                            principal,
                            propertiesForResource,
                            propElement
                        ))
                        yield d
                        d.getResult()
                        break
        else:
            # Do some optimisation of access control calculation by determining any inherited ACLs outside of
            # the child resource loop and supply those to the checkPrivileges on each child.
            filteredaces = waitForDeferred(self.inheritedACEsforChildren(request))
            yield filteredaces
            filteredaces = filteredaces.getResult()

            children = []
            d = waitForDeferred(self.findChildren("infinity", request, lambda x, y: children.append((x, y)),
                                                  privileges=(element.Read(),), inherited_aces=filteredaces))
            yield d
            d.getResult()

            for child, uri in children:
                # Try to read the requested property from this resource
                try:
                    prop = waitForDeferred(child.readProperty(principalPropElement.qname(), request))
                    yield prop
                    prop = prop.getResult()
                    if prop:
                        prop.removeWhitespaceNodes()

                    if prop and len(prop.children) == 1 and isinstance(prop.children[0], element.HRef):
                        # Find principal associated with this property and test it
                        principal = waitForDeferred(request.locateResource(str(prop.children[0])))
                        yield principal
                        principal = principal.getResult()

                        if principal and isPrincipalResource(principal):
                            d = waitForDeferred(principal.principalMatch(myPrincipalURL))
                            yield d
                            matched = d.getResult()
                            if matched:
                                # Check size of results is within limit
                                matchcount += 1
                                if matchcount > max_number_of_matches:
                                    raise NumberOfMatchesWithinLimits(max_number_of_matches)

                                d = waitForDeferred(prop_common.responseForHref(
                                    request,
                                    responses,
                                    element.HRef.fromString(uri),
                                    child,
                                    propertiesForResource,
                                    propElement
                                ))
                                yield d
                                d.getResult()
                except HTTPError:
                    # Just ignore a failure to access the property. We treat this like a property that does not exist
                    # or does not match the principal.
                    pass

    except NumberOfMatchesWithinLimits:
        log.error("Too many matching components in principal-match report")
        raise HTTPError(ErrorResponse(
            responsecode.FORBIDDEN,
            element.NumberOfMatchesWithinLimits()
        ))

    yield MultiStatusResponse(responses)

Example 31

Project: ccs-calendarserver Source File: report_principal_property_search.py
def report_DAV__principal_property_search(self, request, principal_property_search):
    """
    Generate a principal-property-search REPORT. (RFC 3744, section 9.4)
    """

    # Verify root element
    if not isinstance(principal_property_search, element.PrincipalPropertySearch):
        raise ValueError("%s expected as root element, not %s."
                         % (element.PrincipalPropertySearch.sname(), principal_property_search.sname()))

    # Only handle Depth: 0
    depth = request.headers.getHeader("depth", "0")
    if depth != "0":
        log.error("Error in prinicpal-property-search REPORT, Depth set to %s" % (depth,))
        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, "Depth %s not allowed" % (depth,)))

    # Get a single DAV:prop element from the REPORT request body
    propertiesForResource = None
    propElement = None
    propertySearches = []
    applyTo = False
    for child in principal_property_search.children:
        if child.qname() == (dav_namespace, "prop"):
            propertiesForResource = prop_common.propertyListForResource
            propElement = child
        elif child.qname() == (dav_namespace, "apply-to-principal-collection-set"):
            applyTo = True
        elif child.qname() == (dav_namespace, "property-search"):
            props = child.childOfType(element.PropertyContainer)
            props.removeWhitespaceNodes()
            match = child.childOfType(element.Match)
            propertySearches.append((props.children, str(match).lower()))

    def nodeMatch(node, match):
        """
        See if the content of the supplied node matches the supplied text.
        Try to follow the matching guidance in rfc3744 section 9.4.1.
        @param prop:  the property element to match.
        @param match: the text to match against.
        @return:      True if the property matches, False otherwise.
        """
        node.removeWhitespaceNodes()
        for child in node.children:
            if isinstance(child, PCDATAElement):
                comp = str(child).lower()
                if comp.find(match) != -1:
                    return True
            else:
                return nodeMatch(child, match)
        else:
            return False

    def propertySearch(resource, request):
        """
        Test the resource to see if it contains properties matching the
        property-search specification in this report.
        @param resource: the L{DAVFile} for the resource to test.
        @param request:  the current request.
        @return:         True if the resource has matching properties, False otherwise.
        """
        for props, match in propertySearches:
            # Test each property
            for prop in props:
                try:
                    propvalue = waitForDeferred(resource.readProperty(prop.qname(), request))
                    yield propvalue
                    propvalue = propvalue.getResult()
                    if propvalue and not nodeMatch(propvalue, match):
                        yield False
                        return
                except HTTPError:
                    # No property => no match
                    yield False
                    return

        yield True

    propertySearch = deferredGenerator(propertySearch)

    # Run report
    try:
        resources = []
        responses = []
        matchcount = 0

        if applyTo:
            for principalCollection in self.principalCollections():
                uri = principalCollection.principalCollectionURL()
                resource = waitForDeferred(request.locateResource(uri))
                yield resource
                resource = resource.getResult()
                if resource:
                    resources.append((resource, uri))
        else:
            resources.append((self, request.uri))

        # Loop over all collections and principal resources within
        for resource, _ignore_ruri in resources:

            # Do some optimisation of access control calculation by determining any inherited ACLs outside of
            # the child resource loop and supply those to the checkPrivileges on each child.
            filteredaces = waitForDeferred(resource.inheritedACEsforChildren(request))
            yield filteredaces
            filteredaces = filteredaces.getResult()

            children = []
            d = waitForDeferred(resource.findChildren("infinity", request, lambda x, y: children.append((x, y)),
                                                      privileges=(element.Read(),), inherited_aces=filteredaces))
            yield d
            d.getResult()

            for child, uri in children:
                if isPrincipalResource(child):
                    d = waitForDeferred(propertySearch(child, request))
                    yield d
                    d = d.getResult()
                    if d:
                        # Check size of results is within limit
                        matchcount += 1
                        if matchcount > max_number_of_matches:
                            raise NumberOfMatchesWithinLimits(max_number_of_matches)

                        d = waitForDeferred(prop_common.responseForHref(
                            request,
                            responses,
                            element.HRef.fromString(uri),
                            child,
                            propertiesForResource,
                            propElement
                        ))
                        yield d
                        d.getResult()

    except NumberOfMatchesWithinLimits:
        log.error("Too many matching components in prinicpal-property-search report")
        raise HTTPError(ErrorResponse(
            responsecode.FORBIDDEN,
            element.NumberOfMatchesWithinLimits()
        ))

    yield MultiStatusResponse(responses)

Example 32

Project: ccs-calendarserver Source File: static.py
    def quotaSize(self, request):
        """
        Get the size of this resource.
        TODO: Take into account size of dead-properties. Does stat
            include xattrs size?

        @return: an L{Deferred} with a C{int} result containing the size of the resource.
        """
        if self.isCollection():
            def walktree(top):
                """
                Recursively descend the directory tree rooted at top,
                calling the callback function for each regular file

                @param top: L{FilePath} for the directory to walk.
                """

                total = 0
                for f in top.listdir():
                    child = top.child(f)
                    if child.isdir():
                        # It's a directory, recurse into it
                        result = waitForDeferred(walktree(child))
                        yield result
                        total += result.getResult()
                    elif child.isfile():
                        # It's a file, call the callback function
                        total += child.getsize()
                    else:
                        # Unknown file type, print a message
                        pass

                yield total

            walktree = deferredGenerator(walktree)

            return walktree(self.fp)
        else:
            return succeed(self.fp.getsize())

Example 33

Project: ccs-calendarserver Source File: test_resource.py
    def test_findChildren(self):
        """
        This test asserts that we have:
        1) not found any unexpected children
        2) found all expected children

        It does this for all depths C{"0"}, C{"1"}, and C{"infintiy"}
        """
        expected_children = {
            "0": [],
            "1": [
                "/file1",
                "/file2",
                "/dir1/",
                "/dir2/",
            ],
            "infinity": [
                "/file1",
                "/file2",
                "/dir1/",
                "/dir1/subdir1/",
                "/dir2/",
                "/dir2/file1",
                "/dir2/file2",
                "/dir2/subdir1/",
                "/dir2/subdir1/file1",
                "/dir2/subdir1/file2",
            ],
        }

        request = SimpleRequest(self.site, "GET", "/")
        resource = waitForDeferred(request.locateResource("/"))
        yield resource
        resource = resource.getResult()

        def checkChildren(resource, uri):
            self.assertEquals(uri, resource.uri)

            if uri not in expected_children[depth]:
                unexpected_children.append(uri)

            else:
                found_children.append(uri)

        for depth in ["0", "1", "infinity"]:
            found_children = []
            unexpected_children = []

            fc = resource.findChildren(depth, request, checkChildren)
            completed = waitForDeferred(fc)
            yield completed
            completed.getResult()

            self.assertEquals(
                unexpected_children, [],
                "Found unexpected children: %r" % (unexpected_children,)
            )

            expected_children[depth].sort()
            found_children.sort()

            self.assertEquals(expected_children[depth], found_children)

Example 34

Project: ccs-calendarserver Source File: test_resource.py
    def test_findChildrenWithPrivileges(self):
        """
        This test revokes read privileges for the C{"/file2"} and C{"/dir2/"}
        resource to verify that we can not find them giving our unauthenticated
        privileges.
        """

        expected_children = [
            "/file1",
            "/dir1/",
        ]

        request = SimpleRequest(self.site, "GET", "/")
        resource = waitForDeferred(request.locateResource("/"))
        yield resource
        resource = resource.getResult()

        def checkChildren(resource, uri):
            self.assertEquals(uri, resource.uri)

            if uri not in expected_children:
                unexpected_children.append(uri)
            else:
                found_children.append(uri)

        found_children = []
        unexpected_children = []

        privileges = waitForDeferred(resource.currentPrivileges(request))
        yield privileges
        privileges = privileges.getResult()

        fc = resource.findChildren("1", request, checkChildren, privileges)
        completed = waitForDeferred(fc)
        yield completed
        completed.getResult()

        self.assertEquals(
            unexpected_children, [],
            "Found unexpected children: %r" % (unexpected_children,)
        )

        expected_children.sort()
        found_children.sort()

        self.assertEquals(expected_children, found_children)

Example 35

Project: SubliminalCollaborator Source File: root.py
Function: discoverauthority
def discoverAuthority(host, roots, cache=None, p=None):
    warnings.warn(
        'twisted.names.root.discoverAuthority is deprecated since Twisted '
        '10.0.  Use twisted.names.root.Resolver.lookupNameservers instead.',
        category=DeprecationWarning, stacklevel=4)

    if cache is None:
        cache = {}

    rootAuths = list(roots)

    parts = host.rstrip('.').split('.')
    parts.reverse()

    authority = rootAuths.pop()

    soFar = ''
    for part in parts:
        soFar = part + '.' + soFar
        # print '///////',  soFar, authority, p
        msg = defer.waitForDeferred(lookupNameservers(soFar, authority, p))
        yield msg
        msg = msg.getResult()

        newAuth, nameservers = extractAuthority(msg, cache)

        if newAuth is not None:
            # print "newAuth is not None"
            authority = newAuth
        else:
            if nameservers:
                r = str(nameservers[0].payload.name)
                # print 'Recursively discovering authority for', r
                authority = defer.waitForDeferred(discoverAuthority(r, roots, cache, p))
                yield authority
                authority = authority.getResult()
                # print 'Discovered to be', authority, 'for', r
##            else:
##                # print 'Doing address lookup for', soFar, 'at', authority
##                msg = defer.waitForDeferred(lookupAddress(soFar, authority, p))
##                yield msg
##                msg = msg.getResult()
##                records = msg.answers + msg.authority + msg.additional
##                addresses = [r for r in records if r.type == dns.A]
##                if addresses:
##                    authority = addresses[0].payload.dottedQuad()
##                else:
##                    raise IOError("Resolution error")
    # print "Yielding authority", authority
    yield authority

Example 36

Project: SubliminalCollaborator Source File: test_defgen.py
Function: genbuggy
    def _genBuggy(self):
        yield waitForDeferred(getThing())
        1//0

Example 37

Project: droned Source File: droneserver.py
Function: send_command
  @deferredGenerator
  def sendCommand(self, command, keyObj, **kwargs):
      """default method is a short circuit to the server's action handler"""
      result = None
      try:
          services = sys.modules.get('services')
          drone = services.drone.drone
          args = command.split()
          action = drone.get_action(args.pop(0))
          if args:
              args = ' '.join(args)
          else:
              args = ''
          d = maybeDeferred(action, args)
          d.addBoth(drone.formatResults)
          wfd = waitForDeferred(d)
          yield wfd
          result = {self.server: wfd.getResult()}
      except:
          result = Failure()
      yield result