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

Reply via email to