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()