############################################################################## # # Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE # ############################################################################## """ Response class for the FTP Server. """ from ZServer.HTTPResponse import ZServerHTTPResponse from PubCore.ZEvent import Wakeup from cStringIO import StringIO import marshal class FTPResponse(ZServerHTTPResponse): """ Response to an FTP command """ def __str__(self): return '' def outputBody(self): pass def setCookie(self, name, value, **kw): self.cookies[name]=value def appendCookie(self, name, value): self.cookies[name]=self.cookies[name] + value def expireCookie(self, name, **kw): if self.cookies.has_key(name): del self.cookies[name] def _cookie_list(self): return [] def _marshalledBody(self): return marshal.loads(self.body) def setMessage(self, message): self._message = message def getMessage(self): return getattr(self, '_message', '') class CallbackPipe: """ Sends response object to a callback. Doesn't write anything. The callback takes place in Medusa's thread, not the request thread. """ def __init__(self, callback, args): self._callback=callback self._args=args self._producers=[] def close(self): pass def write(self, text, l=None): if text: self._producers.append(text) def finish(self, response): self._response=response Wakeup(self.apply) # move callback to medusas thread def apply(self): result=apply(self._callback, self._args+(self._response,)) # break cycles self._callback=None self._response=None self._args=None return result def make_response(channel, callback, *args): # XXX should this be the FTPResponse constructor instead? r=FTPResponse(stdout=CallbackPipe(callback, args), stderr=StringIO()) r.setHeader('content-type','text/plain') r.cookies=channel.cookies return r