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 f1f807e378 Improve strong etags for caching
f1f807e378 is described below
commit f1f807e378d8c2efb07c50f4d934f990a2ef5c05
Author: remm <[email protected]>
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 74fa278d20..5c25c1fb81 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 1a9d28ac29..da57616bc1 100644
--- a/test/org/apache/catalina/servlets/TestWebdavServlet.java
+++ b/test/org/apache/catalina/servlets/TestWebdavServlet.java
@@ -365,6 +365,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());
@@ -387,6 +390,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 +
@@ -608,15 +624,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: [email protected]
For additional commands, e-mail: [email protected]