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
3
Example 1
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
3
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
3
Example 3
Project: mythbox Source File: test_defgen.py
def _genHandledTerminalAsyncFailure(self, d):
x = waitForDeferred(d)
yield x
try:
x.getResult()
except TerminalException:
pass
3
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
3
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")
3
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)
3
Example 7
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)
3
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")
3
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")
3
Example 10
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
0
Example 11
Project: mythbox Source File: test_manhole.py
def wfd(self, d):
return defer.waitForDeferred(d)
0
Example 12
def _genBuggy(self):
yield waitForDeferred(getThing())
1/0
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."
))
0
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
0
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
0
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)
0
Example 17
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()
0
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()
0
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()
0
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
0
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()
0
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)
0
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()])
0
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),
)
)
0
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
0
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,)
))
0
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
0
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()
0
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)
0
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)
0
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)
0
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())
0
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)
0
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)
0
Example 35
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
0
Example 36
def _genBuggy(self):
yield waitForDeferred(getThing())
1//0
0
Example 37
@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