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

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


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 8c9d51fde3 Timeout allows comma separated values
8c9d51fde3 is described below

commit 8c9d51fde3fded33ad7b932f2904ce822f0c8cb1
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 d3c0245c9f..6ef6cd3eea 100644
--- a/java/org/apache/catalina/servlets/WebdavServlet.java
+++ b/java/org/apache/catalina/servlets/WebdavServlet.java
@@ -1447,27 +1447,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 d7ff773a40..d69e5ea7a5 100644
--- a/test/org/apache/catalina/servlets/TestWebdavServlet.java
+++ b/test/org/apache/catalina/servlets/TestWebdavServlet.java
@@ -553,6 +553,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 +
@@ -562,7 +563,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 94d1863421..c7c5e062f8 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -275,6 +275,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