[Zope-Checkins] CVS: Packages/webdav - NullResource.py:1.39.62.3 Resource.py:1.55.10.7

Sidnei da Silva sidnei at awkly.org
Wed Dec 1 18:02:19 EST 2004


Update of /cvs-repository/Packages/webdav
In directory cvs.zope.org:/tmp/cvs-serv30901/lib/python/webdav

Modified Files:
      Tag: Zope-2_7-branch
	NullResource.py Resource.py 
Log Message:

      - webdav.NullResource: doing a PUT of a large file could
        potentially bring your box to a halt, because the whole file
        would be read into memory just to detect the
        content-type. Added a 'large-file-threshold' directive to
        control the boundary where a file gets read completely into
        memory. The same directive controls the creation of a tmpfile
        vs. reading the whole request into memory on ZServer as well.

      - The 'connection-limit' directive was not taking effect as it
        modified a module-level global that was already bound to the
        functions that used it by the time the directive took
        effect. Modified the functions so that they import the
        variable in the function body instead of at the top of the
        module.


=== Packages/webdav/NullResource.py 1.39.62.2 => 1.39.62.3 ===
--- Packages/webdav/NullResource.py:1.39.62.2	Mon Apr 26 11:42:33 2004
+++ Packages/webdav/NullResource.py	Wed Dec  1 18:01:48 2004
@@ -81,13 +81,16 @@
             ob=File(name, '', body, content_type=typ)
         return ob
 
-    PUT__roles__=('Anonymous',)
+    PUT__roles__ = ('Anonymous',)
     def PUT(self, REQUEST, RESPONSE):
-        """Create a new non-collection resource."""
+        """Create a new non-collection resource.
+        """
+        from ZServer import LARGE_FILE_THRESHOLD
+
         self.dav__init(REQUEST, RESPONSE)
 
-        name=self.__name__
-        parent=self.__parent__
+        name = self.__name__
+        parent = self.__parent__
 
         ifhdr = REQUEST.get_header('If', '')
         if WriteLockInterface.isImplementedBy(parent) and parent.wl_isLocked():
@@ -101,17 +104,40 @@
             # There was an If header, but the parent is not locked
             raise PreconditionFailed
 
-        body=REQUEST.get('BODY', '')
+        # SDS: Only use BODY if the file size is smaller than
+        # LARGE_FILE_THRESHOLD, otherwise read LARGE_FILE_THRESHOLD
+        # bytes from the file which should be enough to trigger
+        # content_type detection, and possibly enough for CMF's
+        # content_type_registry too.
+        #
+        # Note that body here is really just used for detecting the
+        # content type and figuring out the correct factory. The correct
+        # file content will be uploaded on ob.PUT(REQUEST, RESPONSE) after
+        # the object has been created.
+        #
+        # A problem I could see is content_type_registry predicates
+        # that do depend on the whole file being passed here as an
+        # argument. There's none by default that does this though. If
+        # they really do want to look at the file, they should use
+        # REQUEST['BODYFILE'] directly and try as much as possible not
+        # to read the whole file into memory.
+
+        if int(REQUEST.get('CONTENT_LENGTH') or 0) > LARGE_FILE_THRESHOLD:
+            file = REQUEST['BODYFILE']
+            body = file.read(LARGE_FILE_THRESHOLD)
+            file.seek(0)
+        else:
+            body = REQUEST.get('BODY', '')
+
         typ=REQUEST.get_header('content-type', None)
         if typ is None:
             typ, enc=OFS.content_types.guess_content_type(name, body)
 
         factory = getattr(parent, 'PUT_factory', self._default_PUT_factory )
         ob = factory(name, typ, body)
-        ob = (ob is None and
-              self._default_PUT_factory(name, typ, body) or
-              ob
-              )
+        if ob is None:
+            ob = self._default_PUT_factory(name, typ, body)
+
         # We call _verifyObjectPaste with verify_src=0, to see if the
         # user can create this type of object (and we don't need to
         # check the clipboard.
@@ -122,9 +148,11 @@
         except:
             raise Forbidden, sys.exc_info()[1]
 
-        # Delegate actual PUT handling to the new object.
-        ob.PUT(REQUEST, RESPONSE)
+        # Delegate actual PUT handling to the new object,
+        # SDS: But just *after* it has been stored.
         self.__parent__._setObject(name, ob)
+        ob = self.__parent__._getOb(name)
+        ob.PUT(REQUEST, RESPONSE)
 
         RESPONSE.setStatus(201)
         RESPONSE.setBody('')


=== Packages/webdav/Resource.py 1.55.10.6 => 1.55.10.7 ===



More information about the Zope-Checkins mailing list