Beispiel #1
0
        def work():
            for code in (
                    responsecode.CREATED,
                    responsecode.PRECONDITION_FAILED,
                    responsecode.NO_CONTENT,
                    responsecode.PRECONDITION_FAILED,
                    responsecode.NO_CONTENT,
                    responsecode.CREATED,
            ):

                def checkResult(response, code=code):
                    response = IResponse(response)

                    if response.code != code:
                        self.fail(
                            "Incorrect response code for PUT (%s != %s)" %
                            (response.code, code))

                def onError(f):
                    f.trap(HTTPError)
                    return checkResult(f.value.response)

                request = SimpleRequest(self.site, "PUT", dst_uri)
                request.stream = FileStream(file(__file__, "rb"))

                if code == responsecode.CREATED:
                    if os.path.isfile(dst_path):
                        os.remove(dst_path)
                    request.headers.setHeader("if-none-match", ("*", ))
                elif code == responsecode.PRECONDITION_FAILED:
                    request.headers.setHeader("if-none-match", ("*", ))

                yield (request, (checkResult, onError))
Beispiel #2
0
    def test_Quota_DELETE(self):
        """
        Quota change on DELETE
        """
        dst_uri = "/dst"

        def checkPUTResult(response):
            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("Incorrect response code for PUT (%s != %s)"
                          % (response.code, responsecode.CREATED))

            def doDelete(_ignore):
                def checkDELETEResult(response):
                    response = IResponse(response)

                    if response.code != responsecode.NO_CONTENT:
                        self.fail("Incorrect response code for PUT (%s != %s)"
                                  % (response.code, responsecode.NO_CONTENT))

                    return self.checkQuota(0)

                request = SimpleRequest(self.site, "DELETE", dst_uri)
                return self.send(request, checkDELETEResult)

            d = self.checkQuota(100)
            d.addCallback(doDelete)
            return d

        request = SimpleRequest(self.site, "PUT", dst_uri)
        request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), "data", "quota_100.txt"), "rb"))
        return self.send(request, checkPUTResult)
Beispiel #3
0
    def test_Quota_Bad_Adjustment(self):
        """
        Quota adjustment too much
        """
        dst_uri = "/dst"

        def checkPUTResult(response):
            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("Incorrect response code for PUT (%s != %s)"
                          % (response.code, responsecode.CREATED))

            def doBadAdjustment(_ignore):
                def checkAdjustmentResult(_ignore):
                    return self.checkQuota(100)

                d = self.site.resource.quotaSizeAdjust(None, -200)
                d.addCallback(checkAdjustmentResult)
                return d

            d = self.checkQuota(100)
            d.addCallback(doBadAdjustment)
            return d

        request = SimpleRequest(self.site, "PUT", dst_uri)
        request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), "data", "quota_100.txt"), "rb"))
        return self.send(request, checkPUTResult)
 def test_monolithic_ical(self):
     """
     Monolithic iCalendar file in calendar collection
     """
     # FIXME: Should FileStream be OK here?
     dst_file = self.openHolidays()
     stream = FileStream(dst_file)
     return self._test_file_in_calendar("monolithic iCalendar file in calendar", (stream, responsecode.FORBIDDEN))
class DAVFile(SuperDAVFile, DirectoryRenderingMixIn):
    """
    Extended L{txweb2.dav.static.DAVFile} implementation.
    """
    log = Logger()

    def resourceType(self):
        # Allow live property to be overridden by dead property
        if self.deadProperties().contains((dav_namespace, "resourcetype")):
            return self.deadProperties().get((dav_namespace, "resourcetype"))
        if self.isCollection():
            return element.ResourceType.collection  #@UndefinedVariable
        return element.ResourceType.empty  #@UndefinedVariable

    def render(self, request):
        if not self.fp.exists():
            return responsecode.NOT_FOUND

        if self.fp.isdir():
            if request.path[-1] != "/":
                # Redirect to include trailing '/' in URI
                return RedirectResponse(
                    request.unparseURL(path=urllib.quote(
                        urllib.unquote(request.path), safe=':/') + '/'))
            else:
                ifp = self.fp.childSearchPreauth(*self.indexNames)
                if ifp:
                    # Render from the index file
                    return self.createSimilarFile(ifp.path).render(request)

                return self.renderDirectory(request)

        try:
            f = self.fp.open()
        except IOError, e:
            import errno
            if e[0] == errno.EACCES:
                return responsecode.FORBIDDEN
            elif e[0] == errno.ENOENT:
                return responsecode.NOT_FOUND
            else:
                raise

        response = Response()
        response.stream = FileStream(f, 0, self.fp.getsize())

        for (header, value) in (
            ("content-type", self.contentType()),
            ("content-encoding", self.contentEncoding()),
        ):
            if value is not None:
                response.headers.setHeader(header, value)

        return response
    def test_bogus_file(self):
        """
        Bogus file in calendar collection
        """

        # FIXME: Should FileStream be OK here?
        # FIXME: Should FileStream be OK here?
        dst_file = file(__file__)
        self.addCleanup(dst_file.close)
        stream = FileStream(dst_file)
        return self._test_file_in_calendar("bogus file in calendar", (stream, responsecode.FORBIDDEN))
Beispiel #7
0
    def test_PUT_no_parent(self):
        """
        PUT with no parent
        """
        dst_uri = "/put/no/parent"

        def checkResult(response):
            response = IResponse(response)

            if response.code != responsecode.CONFLICT:
                self.fail("Incorrect response code for PUT with no parent (%s != %s)"
                          % (response.code, responsecode.CONFLICT))

        request = SimpleRequest(self.site, "PUT", dst_uri)
        request.stream = FileStream(file(__file__, "rb"))

        return self.send(request, checkResult)
Beispiel #8
0
    def test_Quota_PUT(self):
        """
        Quota change on PUT
        """
        dst_uri = "/dst"

        def checkResult(response):
            response = IResponse(response)

            if response.code != responsecode.CREATED:
                self.fail("Incorrect response code for PUT (%s != %s)"
                          % (response.code, responsecode.CREATED))

            return self.checkQuota(100)

        request = SimpleRequest(self.site, "PUT", dst_uri)
        request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), "data", "quota_100.txt"), "rb"))
        return self.send(request, checkResult)
Beispiel #9
0
        def work():
            dst_uri = "/dst"

            for name in os.listdir(self.docroot):
                if name == "dst":
                    continue

                path = os.path.join(self.docroot, name)

                # Can't really PUT something you can't read
                if not os.path.isfile(path): continue

                def do_test(response):
                    checkResult(response, path)

                request = SimpleRequest(self.site, "PUT", dst_uri)
                request.stream = FileStream(file(path, "rb"))

                yield (request, do_test)
Beispiel #10
0
    def test_Quota_PUT(self):
        """
        Quota change on PUT
        """
        dst_uri = "/dst"

        self.site.resource.setQuotaRoot(None, 90)

        def checkResult(response):
            response = IResponse(response)

            if response.code != responsecode.INSUFFICIENT_STORAGE_SPACE:
                self.fail("Incorrect response code for PUT (%s != %s)"
                          % (response.code, responsecode.INSUFFICIENT_STORAGE_SPACE))

            return self.checkQuota(0)

        request = SimpleRequest(self.site, "PUT", dst_uri)
        request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), "data", "quota_100.txt"), "rb"))
        return self.send(request, checkResult)
Beispiel #11
0
        if datas is None:
            break
        name, value = datas

        numFields += 1
        if numFields == maxFields:
            raise MimeFormatError("Maximum number of fields %d exceeded" % maxFields)

        if name in d:
            d[name].append(value)
        else:
            d[name] = [value]
    yield d
    return
parse_urlencoded = defer.deferredGenerator(parse_urlencoded)


if __name__ == '__main__':
    d = parseMultipartFormData(
        FileStream(open("upload.txt")), "----------0xKhTmLbOuNdArY")
    from twext.python.log import Logger
    log = Logger()
    d.addErrback(log.err)

    def pr(s):
        print(s)
    d.addCallback(pr)


__all__ = ['parseMultipartFormData', 'parse_urlencoded', 'parse_urlencoded_stream', 'MultipartMimeStream', 'MimeFormatError']
Beispiel #12
0
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."
            ))
Beispiel #13
0
        if numFields == maxFields:
            raise MimeFormatError("Maximum number of fields %d exceeded" %
                                  maxFields)

        if name in d:
            d[name].append(value)
        else:
            d[name] = [value]
    yield d
    return


parse_urlencoded = defer.deferredGenerator(parse_urlencoded)

if __name__ == '__main__':
    d = parseMultipartFormData(FileStream(open("upload.txt")),
                               "----------0xKhTmLbOuNdArY")
    from twext.python.log import Logger
    log = Logger()
    d.addErrback(log.err)

    def pr(s):
        print(s)

    d.addCallback(pr)

__all__ = [
    'parseMultipartFormData', 'parse_urlencoded', 'parse_urlencoded_stream',
    'MultipartMimeStream', 'MimeFormatError'
]
Beispiel #14
0
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."
        ))