def __init__(self, code, error): """ @param code: a response code. @param error: an L{davxml.WebDAVElement} identifying the error, or a tuple C{(namespace, name)} with which to create an empty element denoting the error. (The latter is useful in the case of preconditions ans postconditions, not all of which have defined XML element classes.) """ if type(error) is tuple: xml_namespace, xml_name = error class EmptyError(davxml.WebDAVEmptyElement): namespace = xml_namespace name = xml_name error = EmptyError() output = davxml.Error(error).toxml() Response.__init__(self, code=code, stream=output) self.headers.setHeader("content-type", MimeType("text", "xml")) self.error = error
def __init__(self, xml_responses): """ @param xml_responses: an interable of davxml.Response objects. """ multistatus = davxml.MultiStatus(*xml_responses) output = multistatus.toxml() Response.__init__(self, code=responsecode.MULTI_STATUS, stream=davxml.MultiStatus(*xml_responses).toxml()) self.headers.setHeader("content-type", MimeType("text", "xml"))
def __init__(self, code, output): """ @param code: a response code in L{responsecode.RESPONSES}. @param output: the body to be attached to the response """ output = output.encode("utf-8") mime_params = {"charset": "utf-8"} Response.__init__(self, code=code, stream=output) ## Its MIME type, registered by this specification, is "application/xcap-error+xml". self.headers.setHeader("content-type", http_headers.MimeType("application", "xcap-error+xml", mime_params))
def __init__(self, code, output): """ @param code: a response code in L{responsecode.RESPONSES}. @param output: the body to be attached to the response """ output = output.encode("utf-8") mime_params = {"charset": "utf-8"} Response.__init__(self, code=code, stream=output) ## Its MIME type, registered by this specification, is "application/xcap-error+xml". self.headers.setHeader( "content-type", http_headers.MimeType("application", "xcap-error+xml", mime_params))
def __init__(self, msg="", content_type=None): self.msg = msg response = Response(404, stream=msg) if content_type is None: content_type = http_headers.MimeType("text", "plain") response.headers.setHeader("content-type", content_type) HTTPError.__init__(self, response)
def getPieces(self): """Download the next pieces from the peers.""" if self.file.closed: log.msg('Download has been aborted for %s' % self.path) self.stream.allAvailable(remove=True) return self.sort() piece = self.nextFinish while self.outstanding < 4 and self.sitelist and piece < len( self.completePieces): if self.completePieces[piece] == False: # Send a request to the highest ranked peer site = self.sitelist.pop() self.completePieces[piece] = site log.msg('Sending a request for piece %d to peer %r' % (piece, self.peers[site]['peer'])) self.outstanding += 1 path = self.path if self.peers[site]['peer'].mirror: path = self.mirror_path if len(self.completePieces) > 1: df = self.peers[site]['peer'].getRange( path, piece * PIECE_SIZE, (piece + 1) * PIECE_SIZE - 1) else: df = self.peers[site]['peer'].get(path) reactor.callLater( 0, df.addCallbacks, *(self._getPiece, self._getError), **{ 'callbackArgs': (piece, site), 'errbackArgs': (piece, site) }) piece += 1 # Check if we're done if self.outstanding <= 0 and self.nextFinish >= len( self.completePieces): log.msg('Download is complete for %s' % self.path) self.stream.allAvailable(remove=True) # Check if we ran out of peers if self.outstanding <= 0 and not self.sitelist and False in self.completePieces: log.msg("Download failed, no peers left to try.") if self.defer: # Send a return error df = self.defer self.defer = None resp = Response(500, {}, None) df.callback(resp) else: # Already streaming the response, try and abort self.stream.allAvailable(remove=True)
def _removeLock(self, request): """ Remove the lockDiscovery property from the resource. """ ignore = waitForDeferred( deferredGenerator(self.assertNotLocked)(request)) yield ignore ignore = ignore.getResult() self.removeDeadProperty(davxml.LockDiscovery) yield Response(responsecode.NO_CONTENT)
def processLockRequest(resource, request): """ Respond to a LOCK request. (RFC 2518, section 8.10) Relevant notes: """ requestStream = request.stream depth = getDepth(request.headers) #log.error(request.headers.getRawHeaders("X-Litmus")[0]) # generate DAVDocument from request body lockInfo = waitForDeferred( deferredGenerator(parseLockRequest)(requestStream)) yield lockInfo lockInfo = lockInfo.getResult() assertExclusiveLock(lockInfo) assertWriteLock(lockInfo) # we currently only allow lock depths of "0" assertZeroLockDepth(depth) # build the corresponding activelock element # e.g. http://www.webdav.org/specs/rfc2518.html#rfc.section.8.10.8 activeLock = buildActiveLock(lockInfo, depth) # extract the lock token lt = activeLock.childOfType(davxml.LockToken).childOfType(davxml.HRef) # make headers with lock token header lth = http_headers.Headers(rawHeaders={"Lock-Token": [lt]}) ld = davxml.LockDiscovery(activeLock) ignored = waitForDeferred( deferredGenerator(resource._setLock)(ld, request)) yield ignored ignored = ignored.getResult() # debug ignored = waitForDeferred(deferredGenerator(resource._getLock)()) yield ignored ignored = ignored.getResult() pp = davxml.PropertyContainer(ld) yield Response(code=responsecode.OK, headers=lth, stream=stream.MemoryStream(pp.toxml()))
def render(self, request): response = Response() response.stream = MemoryStream(self.renderOutput) return response
def createRequest(self): self.stream = ProducerStream(self.length) self.response = Response(self.code, self.inHeaders, self.stream) self.stream.registerProducer(self, True) del self.inHeaders
def _getPiece(self, response, piece, site): """Process the retrieved headers from the peer.""" if response.code == 404: # Peer no longer has this file, move on log.msg('Peer sharing piece %d no longer has it: %r' % (piece, self.peers[site]['peer'])) self.completePieces[piece] = False if response.stream and response.stream.length: stream.readAndDiscard(response.stream) # Don't add the site back, just move on site = None elif ((len(self.completePieces) > 1 and response.code != 206) or (response.code not in (200, 206))): # Request failed, try a different peer log.msg('Wrong response type %d for piece %d from peer %r' % (response.code, piece, self.peers[site]['peer'])) self.peers[site]['peer'].hashError( 'Peer responded with the wrong type of download: %r' % response.code) self.completePieces[piece] = False self.peers[site]['errors'] = self.peers[site].get('errors', 0) + 1 if response.stream and response.stream.length: stream.readAndDiscard(response.stream) # After 3 errors in a row, drop the peer if self.peers[site]['errors'] >= 3: site = None else: if self.defer: # Start sending the return file df = self.defer self.defer = None self.stream = GrowingFileStream(self.file, self.hash.expSize) # Get the headers from the peer's response headers = {} if response.headers.hasHeader('last-modified'): headers['last-modified'] = response.headers.getHeader( 'last-modified') resp = Response(200, headers, self.stream) df.callback(resp) # Read the response stream to the file log.msg('Streaming piece %d from peer %r' % (piece, self.peers[site]['peer'])) if response.code == 206: df = StreamToFile(self.hash.newPieceHasher(), response.stream, self.file, piece * PIECE_SIZE, PIECE_SIZE).run() else: df = StreamToFile(self.hash.newHasher(), response.stream, self.file).run() reactor.callLater( 0, df.addCallbacks, *(self._gotPiece, self._gotError), **{ 'callbackArgs': (piece, site), 'errbackArgs': (piece, site) }) self.outstanding -= 1 if site: self.sitelist.append(site) else: self.addMirror() self.getPieces()