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

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


The following commit(s) were added to refs/heads/11.0.x by this push:
     new 3fc44630f7 Drop code trying to detect a request body for LOCK and 
PROPFIND
3fc44630f7 is described below

commit 3fc44630f751564cf4d05af2572b26131825830d
Author: remm <r...@apache.org>
AuthorDate: Fri Jan 10 17:35:14 2025 +0100

    Drop code trying to detect a request body for LOCK and PROPFIND
    
    Simply buffer it instead before feeding it to the DOM parser if bytes
    were read. This avoids heavier exception processing when there's no
    body.
    This could be better with HTTP/1.0 requests for example.
---
 .../apache/catalina/servlets/WebdavServlet.java    | 42 ++++++++++++++++++----
 webapps/docs/changelog.xml                         |  4 +++
 2 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/java/org/apache/catalina/servlets/WebdavServlet.java 
b/java/org/apache/catalina/servlets/WebdavServlet.java
index 6495685a73..280a325c2f 100644
--- a/java/org/apache/catalina/servlets/WebdavServlet.java
+++ b/java/org/apache/catalina/servlets/WebdavServlet.java
@@ -17,6 +17,7 @@
 package org.apache.catalina.servlets;
 
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
@@ -56,6 +57,7 @@ import jakarta.servlet.http.HttpServletResponse;
 import org.apache.catalina.WebResource;
 import org.apache.catalina.connector.RequestFacade;
 import org.apache.catalina.util.DOMWriter;
+import org.apache.catalina.util.IOTools;
 import org.apache.catalina.util.XMLWriter;
 import org.apache.tomcat.PeriodicEventListener;
 import org.apache.tomcat.util.IntrospectionUtils;
@@ -833,11 +835,19 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
             }
         }
 
-        if (req.getContentLengthLong() > 0 || 
"chunked".equalsIgnoreCase(req.getHeader("Transfer-Encoding"))) {
+        byte[] body = null;
+        try (InputStream is = req.getInputStream(); ByteArrayOutputStream os = 
new ByteArrayOutputStream()) {
+            IOTools.flow(is, os);
+            body = os.toByteArray();
+        } catch (IOException e) {
+            resp.sendError(WebdavStatus.SC_BAD_REQUEST);
+            return;
+        }
+        if (body.length > 0) {
             DocumentBuilder documentBuilder = getDocumentBuilder();
 
             try {
-                Document document = documentBuilder.parse(new 
InputSource(req.getInputStream()));
+                Document document = documentBuilder.parse(new InputSource(new 
ByteArrayInputStream(body)));
 
                 // Get the root element of the document
                 Element rootElement = document.getDocumentElement();
@@ -1026,8 +1036,20 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
         DocumentBuilder documentBuilder = getDocumentBuilder();
         ArrayList<ProppatchOperation> operations = new ArrayList<>();
 
+        byte[] body = null;
+        try (InputStream is = req.getInputStream(); ByteArrayOutputStream os = 
new ByteArrayOutputStream()) {
+            IOTools.flow(is, os);
+            body = os.toByteArray();
+        } catch (IOException e) {
+            resp.sendError(WebdavStatus.SC_BAD_REQUEST);
+            return;
+        }
+        if (body.length <= 0) {
+            resp.sendError(WebdavStatus.SC_BAD_REQUEST);
+            return;
+        }
         try {
-            Document document = documentBuilder.parse(new 
InputSource(req.getInputStream()));
+            Document document = documentBuilder.parse(new InputSource(new 
ByteArrayInputStream(body)));
 
             // Get the root element of the document
             Element rootElement = document.getDocumentElement();
@@ -1204,7 +1226,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
             return;
         }
 
-        if (req.getContentLengthLong() > 0) {
+        if (req.getContentLengthLong() > 0 || 
"chunked".equalsIgnoreCase(req.getHeader("Transfer-Encoding"))) {
             // No support for MKCOL bodies, which are non standard
             resp.sendError(WebdavStatus.SC_UNSUPPORTED_MEDIA_TYPE);
             return;
@@ -1380,11 +1402,19 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
 
         Node lockInfoNode = null;
 
-        if (req.getContentLengthLong() > 0 || 
"chunked".equalsIgnoreCase(req.getHeader("Transfer-Encoding"))) {
+        byte[] body = null;
+        try (InputStream is = req.getInputStream(); ByteArrayOutputStream os = 
new ByteArrayOutputStream()) {
+            IOTools.flow(is, os);
+            body = os.toByteArray();
+        } catch (IOException e) {
+            resp.sendError(WebdavStatus.SC_BAD_REQUEST);
+            return;
+        }
+        if (body.length > 0) {
             DocumentBuilder documentBuilder = getDocumentBuilder();
 
             try {
-                Document document = documentBuilder.parse(new 
InputSource(req.getInputStream()));
+                Document document = documentBuilder.parse(new InputSource(new 
ByteArrayInputStream(body)));
 
                 // Get the root element of the document
                 Element rootElement = document.getDocumentElement();
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index b6be3e141b..39ef8fec4e 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -127,6 +127,10 @@
         <bug>69527</bug>: Avoid rare cases where a cached resource could be set
         with 0 content length, or could be evicted immediately. (remm)
       </fix>
+      <fix>
+        Fix possible edge cases (such as HTTP/1.0) with trying to detect
+        requests without body for WebDAV LOCK and PROPFIND. (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to