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))
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)
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))
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)
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)
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)
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)
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']
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." ))
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' ]
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." ))