This is an automated email from the ASF dual-hosted git repository. remm 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 64afed8570 Improve strong etags for caching 64afed8570 is described below commit 64afed85707a37309c77abdd1e91b8988acc3438 Author: remm <r...@apache.org> AuthorDate: Wed Nov 20 12:26:34 2024 +0100 Improve strong etags for caching --- .../catalina/webresources/AbstractResource.java | 45 +++++++++------------- .../catalina/webresources/CachedResource.java | 14 ++++++- .../catalina/servlets/TestWebdavServlet.java | 24 ++++++++++-- 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/java/org/apache/catalina/webresources/AbstractResource.java b/java/org/apache/catalina/webresources/AbstractResource.java index 2bd0bdf356..fccc3fb2e2 100644 --- a/java/org/apache/catalina/webresources/AbstractResource.java +++ b/java/org/apache/catalina/webresources/AbstractResource.java @@ -16,13 +16,11 @@ */ package org.apache.catalina.webresources; -import java.io.IOException; import java.io.InputStream; import java.security.MessageDigest; import org.apache.catalina.WebResource; import org.apache.catalina.WebResourceRoot; -import org.apache.catalina.util.IOTools; import org.apache.juli.logging.Log; import org.apache.tomcat.util.buf.HexUtils; import org.apache.tomcat.util.http.FastHttpDateFormat; @@ -89,34 +87,29 @@ public abstract class AbstractResource implements WebResource { long contentLength = getContentLength(); long lastModified = getLastModified(); if (contentLength > 0 && lastModified > 0) { - try (InputStream is = getInputStream()) { - if (contentLength <= 16 * 1024) { - byte[] buf = new byte[(int) contentLength]; - int n = IOTools.readFully(is, buf); - if (n > 0) { - buf = ConcurrentMessageDigest.digest("SHA-1", buf); - strongETag = HexUtils.toHexString(buf); - } else { - strongETag = getETag(); - } + if (contentLength <= 16 * 1024) { + byte[] buf = getContent(); + if (buf != null) { + buf = ConcurrentMessageDigest.digest("SHA-1", buf); + strongETag = HexUtils.toHexString(buf); } else { - byte[] buf = new byte[4096]; - try { - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - while (true) { - int n = is.read(buf); - if (n <= 0) { - break; - } - digest.update(buf, 0, n); + strongETag = getETag(); + } + } else { + byte[] buf = new byte[4096]; + try (InputStream is = getInputStream()) { + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + while (true) { + int n = is.read(buf); + if (n <= 0) { + break; } - strongETag = HexUtils.toHexString(digest.digest()); - } catch (Exception e) { - strongETag = getETag(); + digest.update(buf, 0, n); } + strongETag = HexUtils.toHexString(digest.digest()); + } catch (Exception e) { + strongETag = getETag(); } - } catch (IOException e) { - strongETag = getETag(); } } else { strongETag = getETag(); diff --git a/java/org/apache/catalina/webresources/CachedResource.java b/java/org/apache/catalina/webresources/CachedResource.java index 9a424cc529..83510f9d98 100644 --- a/java/org/apache/catalina/webresources/CachedResource.java +++ b/java/org/apache/catalina/webresources/CachedResource.java @@ -39,7 +39,9 @@ import org.apache.catalina.WebResource; import org.apache.catalina.WebResourceRoot; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; +import org.apache.tomcat.util.buf.HexUtils; import org.apache.tomcat.util.res.StringManager; +import org.apache.tomcat.util.security.ConcurrentMessageDigest; /** * This class is designed to wrap a 'raw' WebResource and providing caching for expensive operations. Inexpensive @@ -74,6 +76,7 @@ public class CachedResource implements WebResource { private volatile Boolean cachedIsVirtual = null; private volatile Long cachedContentLength = null; private final Object cachedContentLengthLock = new Object(); + private volatile String cachedStrongETag = null; public CachedResource(Cache cache, StandardRoot root, String path, long ttl, int objectMaxSizeBytes, @@ -293,7 +296,16 @@ public class CachedResource implements WebResource { @Override public String getStrongETag() { - return webResource.getStrongETag(); + if (cachedStrongETag == null) { + byte[] buf = getContent(); + if (buf != null) { + buf = ConcurrentMessageDigest.digest("SHA-1", buf); + cachedStrongETag = HexUtils.toHexString(buf); + } else { + cachedStrongETag = webResource.getStrongETag(); + } + } + return cachedStrongETag; } @Override diff --git a/test/org/apache/catalina/servlets/TestWebdavServlet.java b/test/org/apache/catalina/servlets/TestWebdavServlet.java index beefc943f7..b8e206bd54 100644 --- a/test/org/apache/catalina/servlets/TestWebdavServlet.java +++ b/test/org/apache/catalina/servlets/TestWebdavServlet.java @@ -364,6 +364,9 @@ public class TestWebdavServlet extends TomcatBaseTest { ctxt.addServletMappingDecoded("/*", "webdav"); tomcat.start(); + ctxt.getResources().setCacheMaxSize(10); + ctxt.getResources().setCacheObjectMaxSize(1); + Client client = new Client(); client.setPort(getPort()); @@ -386,6 +389,19 @@ public class TestWebdavServlet extends TomcatBaseTest { client.processRequest(true); Assert.assertEquals(HttpServletResponse.SC_CREATED, client.getStatusCode()); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 100; i++) { + sb.append(CONTENT); + } + client.setRequest(new String[] { "PUT /file12.txt HTTP/1.1" + SimpleHttpClient.CRLF + + "Host: localhost:" + getPort() + SimpleHttpClient.CRLF + + "Content-Length: " + String.valueOf(sb.length()) + SimpleHttpClient.CRLF + + "Connection: Close" + SimpleHttpClient.CRLF + + SimpleHttpClient.CRLF + sb.toString() }); + client.connect(); + client.processRequest(true); + Assert.assertEquals(HttpServletResponse.SC_CREATED, client.getStatusCode()); + client.setRequest(new String[] { "MKCOL /myfolder HTTP/1.1" + SimpleHttpClient.CRLF + "Host: localhost:" + getPort() + SimpleHttpClient.CRLF + "Connection: Close" + SimpleHttpClient.CRLF + @@ -607,15 +623,15 @@ public class TestWebdavServlet extends TomcatBaseTest { client.processRequest(true); Assert.assertEquals(HttpServletResponse.SC_CREATED, client.getStatusCode()); - StringBuilder sb = new StringBuilder(); + StringBuilder sb2 = new StringBuilder(); for (int i = 0; i < 3000; i++) { - sb.append(CONTENT); + sb2.append(CONTENT); } client.setRequest(new String[] { "PUT /file6.txt HTTP/1.1" + SimpleHttpClient.CRLF + "Host: localhost:" + getPort() + SimpleHttpClient.CRLF + - "Content-Length: " + String.valueOf(sb.length()) + SimpleHttpClient.CRLF + + "Content-Length: " + String.valueOf(sb2.length()) + SimpleHttpClient.CRLF + "Connection: Close" + SimpleHttpClient.CRLF + - SimpleHttpClient.CRLF + sb.toString() }); + SimpleHttpClient.CRLF + sb2.toString() }); client.connect(); client.processRequest(true); Assert.assertEquals(HttpServletResponse.SC_CREATED, client.getStatusCode()); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org