Commit fdd99eb8 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 7b1d2f50
......@@ -26,6 +26,9 @@ Zope Changes
Bugs Fixed
- Collector #1976: FTP STOR command would load the file being
uploaded in memory. Changed to use a TemporaryFile.
- Collector #1904: On Mac OS X avoid a spurious OSError when
zopectl exits.
......
......@@ -27,7 +27,7 @@ import re
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 @@ class FTPRequest(HTTPRequest):
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 @@ class FTPRequest(HTTPRequest):
)
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 @@ class FTPRequest(HTTPRequest):
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)
......
......@@ -352,7 +352,7 @@ class zope_ftp_channel(ftp_channel):
# 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 @@ class zope_ftp_channel(ftp_channel):
)
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 @@ class ContentReceiver:
"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)
......
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