[Checkins] SVN: zope.webdav/trunk/src/zope/webdav/ Fix the parsing of the timeout header to correspond to

Michael Kerrin michael.kerrin at openapp.biz
Sun Aug 27 06:10:03 EDT 2006


Log message for revision 69788:
  Fix the parsing of the timeout header to correspond to
  specification.
  

Changed:
  U   zope.webdav/trunk/src/zope/webdav/locking.py
  U   zope.webdav/trunk/src/zope/webdav/tests/test_locking.py

-=-
Modified: zope.webdav/trunk/src/zope/webdav/locking.py
===================================================================
--- zope.webdav/trunk/src/zope/webdav/locking.py	2006-08-26 18:12:27 UTC (rev 69787)
+++ zope.webdav/trunk/src/zope/webdav/locking.py	2006-08-27 10:09:59 UTC (rev 69788)
@@ -88,34 +88,47 @@
     def getTimeout(self):
         """
         Return a datetime.timedelta object representing the duration of
-        the requested lock token.
+        the requested lock token. This information is passed in the `Timeout'
+        header and corresponds to the following syntax.
 
-        XXX - this method is broken it needs to be able to parse
-        multiple timetypes.
+          TimeOut = "Timeout" ":" 1#TimeType
+          TimeType = ("Second-" DAVTimeOutVal | "Infinite")
+                     ; No LWS allowed within TimeType
+          DAVTimeOutVal = 1*DIGIT
+
+        Multiple TimeType entries are listed in order of performace so this
+        method will return the first valid TimeType converted to a
+        `datetime.timedelta' object or else it returns the default timeout.
         """
-        timeoutheader = self.request.getHeader("timeout", "infinity")
+        timeout = None
+        header = self.request.getHeader("timeout", "infinity")
+        for timeoutheader in header.split(","):
+            timeoutheader = timeoutheader.strip().lower()
 
-        timeoutheader = timeoutheader.strip().lower()
-        t = timeoutheader.split("-")
-
-        if len(t) == 2 and t[0].lower().lower() == "second":
-            th = t[1]
-        elif len(t) == 1 and t[0] == "infinity":
-            th = t[0]
-        else:
-            raise zope.webdav.interfaces.BadRequest(
-                self.request, message = u"Invalid TIMEOUT header")
-
-        if th == "infinite" or th == "infinity":
-            timeout = DEFAULTTIMEOUT
-        else:
-            try:
-                timeout = long(th)
-            except ValueError:
+            t = timeoutheader.split("-")
+            if len(t) == 2 and t[0].lower().lower() == "second":
+                th = t[1]
+            elif len(t) == 1 and (t[0] == "infinite" or t[0] == "infinity"):
+                th = t[0]
+            else:
                 raise zope.webdav.interfaces.BadRequest(
                     self.request, message = u"Invalid TIMEOUT header")
 
-        if timeout > MAXTIMEOUT:
+            if th == "infinite" or th == "infinite" or th == "infinity":
+                timeout = None
+            else:
+                try:
+                    timeout = long(th)
+                except ValueError:
+                    raise zope.webdav.interfaces.BadRequest(
+                        self.request, message = u"Invalid TIMEOUT header")
+
+            if timeout is not None and timeout < MAXTIMEOUT:
+                break # we have gotten a valid timeout we want to use.
+
+            timeout = None # try again to find a valid timeout value.
+
+        if timeout is None:
             timeout = DEFAULTTIMEOUT
 
         return datetime.timedelta(seconds = timeout)

Modified: zope.webdav/trunk/src/zope/webdav/tests/test_locking.py
===================================================================
--- zope.webdav/trunk/src/zope/webdav/tests/test_locking.py	2006-08-26 18:12:27 UTC (rev 69787)
+++ zope.webdav/trunk/src/zope/webdav/tests/test_locking.py	2006-08-27 10:09:59 UTC (rev 69788)
@@ -34,9 +34,9 @@
 from zope.app.container.interfaces import IReadContainer
 from zope.webdav.locking import DEFAULTTIMEOUT, MAXTIMEOUT
 from zope.webdav.locking import UNLOCKMethod, LOCKMethod
-from zope.webdav.testing import etreeSetup, etreeTearDown, assertXMLEqual
 import zope.webdav.publisher
 import zope.webdav.interfaces
+from zope.webdav.testing import etreeSetup, etreeTearDown, assertXMLEqual
 
 _randGen = random.Random(time.time())
 
@@ -75,6 +75,12 @@
         self.assertEqual(lock.getTimeout(),
                          datetime.timedelta(seconds = DEFAULTTIMEOUT))
 
+    def test_timeout_infinite(self):
+        request = TestWebDAVRequest(environ = {"TIMEOUT": "infinite"})
+        lock = LOCKMethod(None, request)
+        self.assertEqual(lock.getTimeout(),
+                         datetime.timedelta(seconds = DEFAULTTIMEOUT))
+
     def test_timeout_second_500(self):
         request = TestWebDAVRequest(environ = {"TIMEOUT": "Second-500"})
         lock = LOCKMethod(None, request)
@@ -98,7 +104,20 @@
         self.assertEqual(lock.getTimeout(),
                          datetime.timedelta(seconds = DEFAULTTIMEOUT))
 
+    def test_timeout_infinity_and_3600(self):
+        request = TestWebDAVRequest(
+            environ = {"TIMEOUT": "Infinite, Second-3600"})
+        lock = LOCKMethod(None, request)
+        self.assertEqual(lock.getTimeout(), datetime.timedelta(seconds = 3600))
 
+    def test_timeout_infinity_and_big_int(self):
+        request = TestWebDAVRequest(
+            environ = {"TIMEOUT": "Infinite, Second-%d" %(MAXTIMEOUT + 100)})
+        lock = LOCKMethod(None, request)
+        self.assertEqual(lock.getTimeout(),
+                         datetime.timedelta(seconds = DEFAULTTIMEOUT))
+
+
 class DAVLockmanager(object):
     interface.implements(zope.webdav.interfaces.IDAVLockmanager)
 



More information about the Checkins mailing list