This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new 55e3a179bf Timeout allows comma separated values
55e3a179bf is described below

commit 55e3a179bfe3dafd657707473acc98acfd4a6f25
Author: remm <[email protected]>
AuthorDate: Fri Jun 12 15:09:24 2026 +0200

    Timeout allows comma separated values
    
    Code review was complaining wrongly, but as I looked at the RFC, I saw
    an example with multiple values in the Timeout header.
---
 .../apache/catalina/servlets/WebdavServlet.java    | 34 +++++++++++++---------
 .../catalina/servlets/TestWebdavServlet.java       |  5 +++-
 webapps/docs/changelog.xml                         |  5 ++++
 3 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/java/org/apache/catalina/servlets/WebdavServlet.java 
b/java/org/apache/catalina/servlets/WebdavServlet.java
index 81e0fbc52e..38f0e0216b 100644
--- a/java/org/apache/catalina/servlets/WebdavServlet.java
+++ b/java/org/apache/catalina/servlets/WebdavServlet.java
@@ -1442,27 +1442,33 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
             }
         }
 
-        // Parsing timeout header
+        // Parsing timeout header (RFC 4918: comma-separated list, pick first 
acceptable)
 
         int lockDuration = DEFAULT_TIMEOUT;
         String lockDurationStr = req.getHeader("Timeout");
         if (lockDurationStr != null) {
-            if (lockDurationStr.startsWith("Second-")) {
-                try {
-                    lockDuration = 
Integer.parseInt(lockDurationStr.substring("Second-".length()));
-                } catch (NumberFormatException e) {
-                    // Ignore
+            String[] timeoutValues = lockDurationStr.split(",");
+            for (String tv : timeoutValues) {
+                tv = tv.trim();
+                if (tv.startsWith("Second-")) {
+                    try {
+                        lockDuration = 
Integer.parseInt(tv.substring("Second-".length()));
+                        break;
+                    } catch (NumberFormatException e) {
+                        // Try the next value if any
+                    }
+                } else if (tv.equals("Infinite")) {
+                    lockDuration = MAX_TIMEOUT;
+                    break;
                 }
-            } else if (lockDurationStr.equals("Infinite")) {
-                lockDuration = MAX_TIMEOUT;
-            }
-            if (lockDuration == 0) {
-                lockDuration = DEFAULT_TIMEOUT;
-            }
-            if (lockDuration > MAX_TIMEOUT) {
-                lockDuration = MAX_TIMEOUT;
             }
         }
+        if (lockDuration == 0) {
+            lockDuration = DEFAULT_TIMEOUT;
+        }
+        if (lockDuration > MAX_TIMEOUT) {
+            lockDuration = MAX_TIMEOUT;
+        }
         lock.expiresAt = System.currentTimeMillis() + (lockDuration * 1000L);
 
         boolean lockCreation = false;
diff --git a/test/org/apache/catalina/servlets/TestWebdavServlet.java 
b/test/org/apache/catalina/servlets/TestWebdavServlet.java
index 2bc6c74c5b..d5eaa5c2f5 100644
--- a/test/org/apache/catalina/servlets/TestWebdavServlet.java
+++ b/test/org/apache/catalina/servlets/TestWebdavServlet.java
@@ -554,6 +554,7 @@ public class TestWebdavServlet extends TomcatBaseTest {
         client.setRequest(new String[] {
                 "LOCK /myfolder HTTP/1.1" + CRLF +
                     "Host: localhost:" + getPort() + CRLF +
+                    "Timeout: Second-fwe, Second-259" + CRLF +
                     "Content-Length: " + LOCK_BODY.length() + CRLF +
                     "Connection: Close" + CRLF +
                     CRLF +
@@ -563,7 +564,9 @@ public class TestWebdavServlet extends TomcatBaseTest {
         client.connect();
         client.processRequest(true);
         Assert.assertEquals(HttpServletResponse.SC_OK, client.getStatusCode());
-        Assert.assertTrue(client.getResponseBody().contains("urn:uuid:"));
+        String clientBody = client.getResponseBody();
+        Assert.assertTrue(clientBody.contains("urn:uuid:"));
+        Assert.assertTrue(clientBody.contains("Second-25"));
         String lockToken = null;
         for (String header : client.getResponseHeaders()) {
             if (header.startsWith("Lock-Token: ")) {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 42de4065aa..96668ef7b8 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -386,6 +386,11 @@
         Missing URL decoding when processing <code>addMapping</code> on a
         Servlet registration. (remm)
       </fix>
+      <fix>
+        The <code>Timeout</code> WebDAV header allows comma separated values
+        (according to the examples in the RFC). Use the first acceptable value.
+        (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to