Commit 5a762139 authored by Sidnei da Silva's avatar Sidnei da Silva

     - Collector #1976: FTP STOR command would load the file being
       uploaded in memory. Changed to use a TemporaryFile.
parent e5931835
...@@ -27,6 +27,9 @@ Zope Changes ...@@ -27,6 +27,9 @@ Zope Changes
Bugs fixed 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 - OFS ObjectManager: Fixed list_imports() to tolerate missing
import directories. import directories.
......
...@@ -27,7 +27,7 @@ import re ...@@ -27,7 +27,7 @@ import re
class FTPRequest(HTTPRequest): class FTPRequest(HTTPRequest):
def __init__(self, path, command, channel, response, stdin=None, 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 # we need to store the globbing information to pass it
# to the ZPublisher and the manage_FTPlist function # to the ZPublisher and the manage_FTPlist function
...@@ -35,9 +35,12 @@ class FTPRequest(HTTPRequest): ...@@ -35,9 +35,12 @@ class FTPRequest(HTTPRequest):
self.globbing = globbing self.globbing = globbing
self.recursive= recursive self.recursive= recursive
if stdin is None: stdin=StringIO() if stdin is None:
size = 0
stdin = StringIO()
if environ is None: 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 self._orig_env=environ
HTTPRequest.__init__(self, stdin, environ, response, clean=1) HTTPRequest.__init__(self, stdin, environ, response, clean=1)
...@@ -61,7 +64,7 @@ class FTPRequest(HTTPRequest): ...@@ -61,7 +64,7 @@ class FTPRequest(HTTPRequest):
) )
return r return r
def _get_env(self, path, command, channel, stdin): def _get_env(self, path, command, channel, stdin, size):
"Returns a CGI style environment" "Returns a CGI style environment"
env={} env={}
env['SCRIPT_NAME']='/%s' % channel.module env['SCRIPT_NAME']='/%s' % channel.module
...@@ -109,9 +112,10 @@ class FTPRequest(HTTPRequest): ...@@ -109,9 +112,10 @@ class FTPRequest(HTTPRequest):
env['QUERY_STRING']='id=%s&new_id=%s' % (args[0],args[1]) env['QUERY_STRING']='id=%s&new_id=%s' % (args[0],args[1])
elif command=='STOR': elif command=='STOR':
env['PATH_INFO']=self._join_paths(channel.path, path) env['PATH_INFO'] = self._join_paths(channel.path, path)
env['REQUEST_METHOD']='PUT' env['REQUEST_METHOD'] = 'PUT'
env['CONTENT_LENGTH']=len(stdin.getvalue()) env['CONTENT_LENGTH'] = long(size)
else: else:
env['PATH_INFO']=self._join_paths(channel.path, path, command) env['PATH_INFO']=self._join_paths(channel.path, path, command)
......
...@@ -352,7 +352,7 @@ class zope_ftp_channel(ftp_channel): ...@@ -352,7 +352,7 @@ class zope_ftp_channel(ftp_channel):
# Right now we are limited in the errors we can issue, since # Right now we are limited in the errors we can issue, since
# we agree to accept the file before checking authorization # 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 ( self.respond (
'150 Opening %s connection for %s' % ( '150 Opening %s connection for %s' % (
self.type_map[self.current_mode], self.type_map[self.current_mode],
...@@ -361,14 +361,15 @@ class zope_ftp_channel(ftp_channel): ...@@ -361,14 +361,15 @@ class zope_ftp_channel(ftp_channel):
) )
self.make_recv_channel(fd) 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' 'callback to do the STOR, after we have the input'
response=make_response(self, self.stor_completion) response = make_response(self, self.stor_completion)
request=FTPRequest(path,'STOR',self,response,stdin=data) request = FTPRequest(path, 'STOR', self, response,
handle(self.module,request,response) stdin=data, size=size)
handle(self.module, request, response)
def stor_completion(self,response): def stor_completion(self, response):
status=response.getStatus() status = response.getStatus()
if status in (200, 201, 204, 302): if status in (200, 201, 204, 302):
self.client_dc.channel.respond('226 Transfer complete.') self.client_dc.channel.respond('226 Transfer complete.')
...@@ -559,19 +560,21 @@ class ContentReceiver: ...@@ -559,19 +560,21 @@ class ContentReceiver:
"Write-only file object used to receive data from FTP" "Write-only file object used to receive data from FTP"
def __init__(self,callback,*args): def __init__(self,callback,*args):
self.data=StringIO() from tempfile import TemporaryFile
self.callback=callback self.data = TemporaryFile('w+b')
self.args=args self.callback = callback
self.args = args
def write(self,data): def write(self,data):
self.data.write(data) self.data.write(data)
def close(self): def close(self):
size = self.data.tell()
self.data.seek(0) self.data.seek(0)
args=self.args+(self.data,) args = self.args + (self.data, size)
c=self.callback c = self.callback
self.callback=None self.callback = None
self.args=None self.args = None
c(*args) c(*args)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment