Log message for revision 40805:
  
        - Collector #1976: FTP STOR command would load the file being
          uploaded in memory. Changed to use a TemporaryFile.
  

Changed:
  U   Zope/branches/Zope-2_8-branch/doc/CHANGES.txt
  U   Zope/branches/Zope-2_8-branch/lib/python/ZServer/FTPRequest.py
  U   Zope/branches/Zope-2_8-branch/lib/python/ZServer/FTPServer.py

-=-
Modified: Zope/branches/Zope-2_8-branch/doc/CHANGES.txt
===================================================================
--- Zope/branches/Zope-2_8-branch/doc/CHANGES.txt       2005-12-16 11:58:29 UTC 
(rev 40804)
+++ Zope/branches/Zope-2_8-branch/doc/CHANGES.txt       2005-12-16 12:28:10 UTC 
(rev 40805)
@@ -26,6 +26,9 @@
 
     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.
 

Modified: Zope/branches/Zope-2_8-branch/lib/python/ZServer/FTPRequest.py
===================================================================
--- Zope/branches/Zope-2_8-branch/lib/python/ZServer/FTPRequest.py      
2005-12-16 11:58:29 UTC (rev 40804)
+++ Zope/branches/Zope-2_8-branch/lib/python/ZServer/FTPRequest.py      
2005-12-16 12:28:10 UTC (rev 40805)
@@ -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/Zope-2_8-branch/lib/python/ZServer/FTPServer.py
===================================================================
--- Zope/branches/Zope-2_8-branch/lib/python/ZServer/FTPServer.py       
2005-12-16 11:58:29 UTC (rev 40804)
+++ Zope/branches/Zope-2_8-branch/lib/python/ZServer/FTPServer.py       
2005-12-16 12:28:10 UTC (rev 40805)
@@ -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

Reply via email to