This is an automated email from the ASF dual-hosted git repository. remm 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 6863bc912b Drop code trying to detect a request body for LOCK and PROPFIND 6863bc912b is described below commit 6863bc912b2da71d3aab58a488864979dcf29a34 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 a2fda90b3a..b478676dde 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -154,6 +154,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