[Zope-Checkins] SVN: Zope/trunk/ DAV: litmus' cond_put_unlocked
test (#22) exposed a bug in
Chris McDonough
chrism at plope.com
Sun Jun 17 11:58:27 EDT 2007
Log message for revision 76732:
DAV: litmus' cond_put_unlocked test (#22) exposed a bug in
webdav.Resource.dav__simpleifhandler. If the resource is not
locked, and a DAV request contains an If header, no token can
possibly match and we must return a 412 Precondition Failed
instead of 204 No Content.
Changed:
U Zope/trunk/doc/CHANGES.txt
U Zope/trunk/lib/python/webdav/Lockable.py
U Zope/trunk/lib/python/webdav/Resource.py
U Zope/trunk/lib/python/webdav/tests/testLockItem.py
A Zope/trunk/lib/python/webdav/tests/testLockable.py
U Zope/trunk/lib/python/webdav/tests/testResource.py
-=-
Modified: Zope/trunk/doc/CHANGES.txt
===================================================================
--- Zope/trunk/doc/CHANGES.txt 2007-06-17 15:01:29 UTC (rev 76731)
+++ Zope/trunk/doc/CHANGES.txt 2007-06-17 15:58:27 UTC (rev 76732)
@@ -97,6 +97,12 @@
Bugs Fixed
+ - DAV: litmus' cond_put_unlocked test (#22) exposed a bug in
+ webdav.Resource.dav__simpleifhandler. If the resource is not
+ locked, and a DAV request contains an If header, no token can
+ possibly match and we must return a 412 Precondition Failed
+ instead of 204 No Content.
+
- DAV: litmus' cond_put_corrupt_token test (#18) exposed a bug
in webdav.Resource.dav__simpleifhandler. If the resource is
locked at all, and a DAV request contains an If header, and
Modified: Zope/trunk/lib/python/webdav/Lockable.py
===================================================================
--- Zope/trunk/lib/python/webdav/Lockable.py 2007-06-17 15:01:29 UTC (rev 76731)
+++ Zope/trunk/lib/python/webdav/Lockable.py 2007-06-17 15:58:27 UTC (rev 76732)
@@ -152,5 +152,9 @@
def wl_isLocked(ob):
""" Returns true if the object is locked, returns 0 if the object
is not locked or does not implement the WriteLockInterface """
+ return wl_isLockable(ob) and ob.wl_isLocked()
+
+def wl_isLockable(ob):
return (IWriteLock.providedBy(ob) or
- WriteLockInterface.isImplementedBy(ob)) and ob.wl_isLocked()
+ WriteLockInterface.isImplementedBy(ob))
+
Modified: Zope/trunk/lib/python/webdav/Resource.py
===================================================================
--- Zope/trunk/lib/python/webdav/Resource.py 2007-06-17 15:01:29 UTC (rev 76731)
+++ Zope/trunk/lib/python/webdav/Resource.py 2007-06-17 15:58:27 UTC (rev 76732)
@@ -113,12 +113,27 @@
def dav__simpleifhandler(self, request, response, method='PUT',
col=0, url=None, refresh=0):
ifhdr = request.get_header('If', None)
- if Lockable.wl_isLocked(self) and (not ifhdr):
- raise Locked, "Resource is locked."
- if not ifhdr: return None
- if not Lockable.wl_isLocked(self): return None
+ lockable = Lockable.wl_isLockable(self)
+ if not lockable:
+ # degenerate case, we shouldnt have even called this method.
+ return None
+ locked = self.wl_isLocked()
+
+ if locked and (not ifhdr):
+ raise Locked('Resource is locked.')
+
+ if not ifhdr:
+ return None
+
+ if (not locked):
+ # we have an if header but the resource isn't locked, we
+ # can shortcut checking the tags in the if header; no token
+ # can possibly match
+ raise PreconditionFailed(
+ 'Resource not locked but If header specified')
+
# Since we're a simple if handler, and since some clients don't
# pass in the port information in the resource part of an If
# header, we're only going to worry about if the paths compare
Modified: Zope/trunk/lib/python/webdav/tests/testLockItem.py
===================================================================
--- Zope/trunk/lib/python/webdav/tests/testLockItem.py 2007-06-17 15:01:29 UTC (rev 76731)
+++ Zope/trunk/lib/python/webdav/tests/testLockItem.py 2007-06-17 15:58:27 UTC (rev 76732)
@@ -17,7 +17,6 @@
verifyClass(ILockItem, LockItem)
-
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(TestLockItem),
Added: Zope/trunk/lib/python/webdav/tests/testLockable.py
===================================================================
--- Zope/trunk/lib/python/webdav/tests/testLockable.py (rev 0)
+++ Zope/trunk/lib/python/webdav/tests/testLockable.py 2007-06-17 15:58:27 UTC (rev 76732)
@@ -0,0 +1,39 @@
+import unittest
+
+class TestUtilFunctions(unittest.TestCase):
+ def test_wl_isLocked(self):
+ from webdav.Lockable import wl_isLocked
+ unlockable = UnlockableResource()
+ self.failIf(wl_isLocked(unlockable))
+ lockable_unlocked = LockableResource(locked=False)
+ self.failIf(wl_isLocked(lockable_unlocked))
+ lockable_locked = LockableResource(locked=True)
+ self.failUnless(wl_isLocked(lockable_locked))
+
+ def test_wl_isLockable(self):
+ from webdav.Lockable import wl_isLockable
+ unlockable = UnlockableResource()
+ self.failIf(wl_isLockable(unlockable))
+ lockable = LockableResource(locked=False)
+ self.failUnless(wl_isLockable(lockable))
+
+from webdav.interfaces import IWriteLock
+from zope.interface import implements
+
+class LockableResource:
+ implements(IWriteLock)
+ def __init__(self, locked):
+ self.locked = locked
+ def wl_isLocked(self):
+ return self.locked
+
+class UnlockableResource:
+ pass
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(TestUtilFunctions),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Property changes on: Zope/trunk/lib/python/webdav/tests/testLockable.py
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: Zope/trunk/lib/python/webdav/tests/testResource.py
===================================================================
--- Zope/trunk/lib/python/webdav/tests/testResource.py 2007-06-17 15:01:29 UTC (rev 76731)
+++ Zope/trunk/lib/python/webdav/tests/testResource.py 2007-06-17 15:58:27 UTC (rev 76732)
@@ -56,6 +56,26 @@
from webdav.common import Locked
self.assertRaises(Locked, inst.MOVE, request, response)
+ def test_dav__simpleifhandler_fail_cond_put_unlocked(self):
+ """
+ DAV: litmus' cond_put_unlocked test (#22) exposed a bug in
+ webdav.Resource.dav__simpleifhandler. If the resource is not
+ locked, and a DAV request contains an If header, no token can
+ possibly match and we must return a 412 Precondition Failed
+ instead of 204 No Content.
+ """
+ ifhdr = 'If: (<locktoken:foo>)'
+ request = DummyRequest({'URL':'http://example.com/foo/PUT'},
+ {'If':ifhdr})
+ response = DummyResponse()
+ inst = self._makeOne()
+ from zope.interface import directlyProvides
+ from webdav.interfaces import IWriteLock
+ directlyProvides(inst, IWriteLock)
+ from webdav.common import PreconditionFailed
+ self.assertRaises(PreconditionFailed, inst.dav__simpleifhandler,
+ request, response)
+
def test_dav__simpleifhandler_cond_put_corrupt_token(self):
"""
DAV: litmus' cond_put_corrupt_token test (#18) exposed a bug
More information about the Zope-Checkins
mailing list