Log message for revision 40806: - Collector #1976: FTP STOR command would load the file being uploaded in memory. Changed to use a TemporaryFile.
Changed: U Zope/branches/2.9/doc/CHANGES.txt U Zope/branches/2.9/lib/python/ZServer/FTPRequest.py U Zope/branches/2.9/lib/python/ZServer/FTPServer.py -=- Modified: Zope/branches/2.9/doc/CHANGES.txt =================================================================== --- Zope/branches/2.9/doc/CHANGES.txt 2005-12-16 12:28:10 UTC (rev 40805) +++ Zope/branches/2.9/doc/CHANGES.txt 2005-12-16 12:49:12 UTC (rev 40806) @@ -27,6 +27,9 @@ Bugs fixed + - Collector #1976: FTP STOR command would load the file being + uploaded in memory. Changed to use a TemporaryFile. + - OFS ObjectManager: Fixed list_imports() to tolerate missing import directories. Modified: Zope/branches/2.9/lib/python/ZServer/FTPRequest.py =================================================================== --- Zope/branches/2.9/lib/python/ZServer/FTPRequest.py 2005-12-16 12:28:10 UTC (rev 40805) +++ Zope/branches/2.9/lib/python/ZServer/FTPRequest.py 2005-12-16 12:49:12 UTC (rev 40806) @@ -27,7 +27,7 @@ class FTPRequest(HTTPRequest): def __init__(self, path, command, channel, response, stdin=None, - environ=None,globbing=None,recursive=0): + environ=None, globbing=None, recursive=0, size=None): # we need to store the globbing information to pass it # to the ZPublisher and the manage_FTPlist function @@ -35,9 +35,12 @@ self.globbing = globbing self.recursive= recursive - if stdin is None: stdin=StringIO() + if stdin is None: + size = 0 + stdin = StringIO() + if environ is None: - environ=self._get_env(path, command, channel, stdin) + environ = self._get_env(path, command, channel, stdin, size) self._orig_env=environ HTTPRequest.__init__(self, stdin, environ, response, clean=1) @@ -61,7 +64,7 @@ ) return r - def _get_env(self, path, command, channel, stdin): + def _get_env(self, path, command, channel, stdin, size): "Returns a CGI style environment" env={} env['SCRIPT_NAME']='/%s' % channel.module @@ -109,9 +112,10 @@ env['QUERY_STRING']='id=%s&new_id=%s' % (args[0],args[1]) elif command=='STOR': - env['PATH_INFO']=self._join_paths(channel.path, path) - env['REQUEST_METHOD']='PUT' - env['CONTENT_LENGTH']=len(stdin.getvalue()) + env['PATH_INFO'] = self._join_paths(channel.path, path) + env['REQUEST_METHOD'] = 'PUT' + env['CONTENT_LENGTH'] = long(size) + else: env['PATH_INFO']=self._join_paths(channel.path, path, command) Modified: Zope/branches/2.9/lib/python/ZServer/FTPServer.py =================================================================== --- Zope/branches/2.9/lib/python/ZServer/FTPServer.py 2005-12-16 12:28:10 UTC (rev 40805) +++ Zope/branches/2.9/lib/python/ZServer/FTPServer.py 2005-12-16 12:49:12 UTC (rev 40806) @@ -352,7 +352,7 @@ # Right now we are limited in the errors we can issue, since # we agree to accept the file before checking authorization - fd=ContentReceiver(self.stor_callback, line[1]) + fd = ContentReceiver(self.stor_callback, line[1]) self.respond ( '150 Opening %s connection for %s' % ( self.type_map[self.current_mode], @@ -361,14 +361,15 @@ ) self.make_recv_channel(fd) - def stor_callback(self,path,data): + def stor_callback(self, path, data, size): 'callback to do the STOR, after we have the input' - response=make_response(self, self.stor_completion) - request=FTPRequest(path,'STOR',self,response,stdin=data) - handle(self.module,request,response) + response = make_response(self, self.stor_completion) + request = FTPRequest(path, 'STOR', self, response, + stdin=data, size=size) + handle(self.module, request, response) - def stor_completion(self,response): - status=response.getStatus() + def stor_completion(self, response): + status = response.getStatus() if status in (200, 201, 204, 302): self.client_dc.channel.respond('226 Transfer complete.') @@ -559,19 +560,21 @@ "Write-only file object used to receive data from FTP" def __init__(self,callback,*args): - self.data=StringIO() - self.callback=callback - self.args=args + from tempfile import TemporaryFile + self.data = TemporaryFile('w+b') + self.callback = callback + self.args = args def write(self,data): self.data.write(data) def close(self): + size = self.data.tell() self.data.seek(0) - args=self.args+(self.data,) - c=self.callback - self.callback=None - self.args=None + args = self.args + (self.data, size) + c = self.callback + self.callback = None + self.args = None c(*args) _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins