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 4d11acc4a4 Allow readOnly attribute configuration on the Resources
4d11acc4a4 is described below

commit 4d11acc4a4dd9762477882683f8b202a7238b8b5
Author: remm <r...@apache.org>
AuthorDate: Mon Dec 23 11:08:09 2024 +0100

    Allow readOnly attribute configuration on the Resources
    
    Use the exposed attribute value in the default and WebDAV Servlets in
    addition to the existing readOnly configuration.
---
 java/org/apache/catalina/WebResourceRoot.java        | 17 +++++++++++++++++
 .../org/apache/catalina/servlets/DefaultServlet.java | 18 ++++++++++++++----
 java/org/apache/catalina/servlets/WebdavServlet.java | 20 ++++++++++----------
 .../apache/catalina/webresources/DirResourceSet.java |  9 ++++++---
 .../apache/catalina/webresources/StandardRoot.java   | 12 ++++++++++++
 webapps/docs/changelog.xml                           |  7 +++++++
 webapps/docs/config/resources.xml                    |  6 ++++++
 7 files changed, 72 insertions(+), 17 deletions(-)

diff --git a/java/org/apache/catalina/WebResourceRoot.java 
b/java/org/apache/catalina/WebResourceRoot.java
index fb6b43c002..f96dc7d7e8 100644
--- a/java/org/apache/catalina/WebResourceRoot.java
+++ b/java/org/apache/catalina/WebResourceRoot.java
@@ -414,6 +414,23 @@ public interface WebResourceRoot extends Lifecycle {
         // NO-OP
     }
 
+    /**
+     * Set if the main resources are read only.
+     *
+     * @param readOnly the value
+     */
+    default void setReadOnly(boolean readOnly) {
+        // NO-OP
+    }
+
+    /**
+     * @return {@code true} if the main resources are read only, otherwise 
{@code false}. The default implementation
+     *   returns {@code false}.
+     */
+    default boolean isReadOnly() {
+        return false;
+    }
+
     enum ResourceSetType {
         PRE,
         RESOURCE_JAR,
diff --git a/java/org/apache/catalina/servlets/DefaultServlet.java 
b/java/org/apache/catalina/servlets/DefaultServlet.java
index 808f90ad23..1c56e31f26 100644
--- a/java/org/apache/catalina/servlets/DefaultServlet.java
+++ b/java/org/apache/catalina/servlets/DefaultServlet.java
@@ -493,6 +493,16 @@ public class DefaultServlet extends HttpServlet {
     }
 
 
+    protected boolean isListings() {
+        return listings;
+    }
+
+
+    protected boolean isReadOnly() {
+        return readOnly || resources.isReadOnly();
+    }
+
+
     @Override
     protected void service(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
 
@@ -555,7 +565,7 @@ public class DefaultServlet extends HttpServlet {
         allow.append("OPTIONS, GET, HEAD, POST");
 
         // PUT and DELETE depend on readonly
-        if (!readOnly) {
+        if (!isReadOnly()) {
             allow.append(", PUT, DELETE");
         }
 
@@ -584,7 +594,7 @@ public class DefaultServlet extends HttpServlet {
     @Override
     protected void doPut(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
 
-        if (readOnly) {
+        if (isReadOnly()) {
             sendNotAllowed(req, resp);
             return;
         }
@@ -707,7 +717,7 @@ public class DefaultServlet extends HttpServlet {
     @Override
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
 
-        if (readOnly) {
+        if (isReadOnly()) {
             sendNotAllowed(req, resp);
             return;
         }
@@ -919,7 +929,7 @@ public class DefaultServlet extends HttpServlet {
 
             // Skip directory listings if we have been configured to
             // suppress them
-            if (!listings) {
+            if (!isListings()) {
                 response.sendError(HttpServletResponse.SC_NOT_FOUND,
                         sm.getString("defaultServlet.missingResource", 
request.getRequestURI()));
                 return;
diff --git a/java/org/apache/catalina/servlets/WebdavServlet.java 
b/java/org/apache/catalina/servlets/WebdavServlet.java
index c7f7cfad55..6495685a73 100644
--- a/java/org/apache/catalina/servlets/WebdavServlet.java
+++ b/java/org/apache/catalina/servlets/WebdavServlet.java
@@ -751,7 +751,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
         // if the resource does not exist.
         StringBuilder methodsAllowed = new StringBuilder("OPTIONS, GET, POST, 
HEAD");
 
-        if (!readOnly) {
+        if (!isReadOnly()) {
             methodsAllowed.append(", DELETE");
             if (!resource.isDirectory()) {
                 methodsAllowed.append(", PUT");
@@ -765,7 +765,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
 
         methodsAllowed.append(", LOCK, UNLOCK, PROPPATCH, COPY, MOVE");
 
-        if (listings) {
+        if (isListings()) {
             methodsAllowed.append(", PROPFIND");
         }
 
@@ -796,7 +796,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
      */
     protected void doPropfind(HttpServletRequest req, HttpServletResponse 
resp) throws ServletException, IOException {
 
-        if (!listings) {
+        if (!isListings()) {
             sendNotAllowed(req, resp);
             return;
         }
@@ -1013,7 +1013,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
             return;
         }
 
-        if (readOnly) {
+        if (isReadOnly()) {
             resp.sendError(WebdavStatus.SC_FORBIDDEN);
             return;
         }
@@ -1194,7 +1194,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
             return;
         }
 
-        if (readOnly) {
+        if (isReadOnly()) {
             resp.sendError(WebdavStatus.SC_FORBIDDEN);
             return;
         }
@@ -1221,7 +1221,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
     @Override
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
 
-        if (readOnly) {
+        if (isReadOnly()) {
             sendNotAllowed(req, resp);
             return;
         }
@@ -1268,7 +1268,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
      */
     protected void doCopy(HttpServletRequest req, HttpServletResponse resp) 
throws IOException {
 
-        if (readOnly) {
+        if (isReadOnly()) {
             resp.sendError(WebdavStatus.SC_FORBIDDEN);
             return;
         }
@@ -1289,7 +1289,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
      */
     protected void doMove(HttpServletRequest req, HttpServletResponse resp) 
throws IOException {
 
-        if (readOnly) {
+        if (isReadOnly()) {
             resp.sendError(WebdavStatus.SC_FORBIDDEN);
             return;
         }
@@ -1318,7 +1318,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
      */
     protected void doLock(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
 
-        if (readOnly) {
+        if (isReadOnly()) {
             resp.sendError(WebdavStatus.SC_FORBIDDEN);
             return;
         }
@@ -1731,7 +1731,7 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
      */
     protected void doUnlock(HttpServletRequest req, HttpServletResponse resp) 
throws IOException {
 
-        if (readOnly) {
+        if (isReadOnly()) {
             resp.sendError(WebdavStatus.SC_FORBIDDEN);
             return;
         }
diff --git a/java/org/apache/catalina/webresources/DirResourceSet.java 
b/java/org/apache/catalina/webresources/DirResourceSet.java
index f1d4e86199..026c61a065 100644
--- a/java/org/apache/catalina/webresources/DirResourceSet.java
+++ b/java/org/apache/catalina/webresources/DirResourceSet.java
@@ -101,13 +101,14 @@ public class DirResourceSet extends 
AbstractFileResourceSet implements WebResour
         checkPath(path);
         String webAppMount = getWebAppMount();
         WebResourceRoot root = getRoot();
+        boolean readOnly = isReadOnly();
         if (path.startsWith(webAppMount)) {
             /*
              * Lock the path for reading until the WebResource has been 
constructed. The lock prevents concurrent reads
              * and writes (e.g. HTTP GET and PUT / DELETE) for the same path 
causing corruption of the FileResource
              * where some of the fields are set as if the file exists and some 
as set as if it does not.
              */
-            ResourceLock lock = lockForRead(path);
+            ResourceLock lock = readOnly ? null : lockForRead(path);
             try {
                 File f = file(path.substring(webAppMount.length()), false);
                 if (f == null) {
@@ -119,9 +120,11 @@ public class DirResourceSet extends 
AbstractFileResourceSet implements WebResour
                 if (f.isDirectory() && path.charAt(path.length() - 1) != '/') {
                     path = path + '/';
                 }
-                return new FileResource(root, path, f, isReadOnly(), 
getManifest(), this, lock.key);
+                return new FileResource(root, path, f, readOnly, 
getManifest(), this, readOnly ? null : lock.key);
             } finally {
-                unlockForRead(lock);
+                if (!readOnly) {
+                    unlockForRead(lock);
+                }
             }
         } else {
             return new EmptyResource(root, path);
diff --git a/java/org/apache/catalina/webresources/StandardRoot.java 
b/java/org/apache/catalina/webresources/StandardRoot.java
index 2cb98e277a..7c5c08dbea 100644
--- a/java/org/apache/catalina/webresources/StandardRoot.java
+++ b/java/org/apache/catalina/webresources/StandardRoot.java
@@ -67,6 +67,7 @@ public class StandardRoot extends LifecycleMBeanBase 
implements WebResourceRoot
 
     private Context context;
     private boolean allowLinking = false;
+    private boolean readOnly = false;
     private final List<WebResourceSet> preResources = new ArrayList<>();
     private WebResourceSet main;
     private final List<WebResourceSet> classResources = new ArrayList<>();
@@ -657,6 +658,16 @@ public class StandardRoot extends LifecycleMBeanBase 
implements WebResourceRoot
     }
 
 
+    @Override
+    public boolean isReadOnly() {
+        return (readOnly || main == null || main.isReadOnly());
+    }
+
+    @Override
+    public void setReadOnly(boolean readOnly) {
+        this.readOnly = readOnly;
+    }
+
     // ----------------------------------------------------------- JMX 
Lifecycle
     @Override
     protected String getDomainInternal() {
@@ -743,6 +754,7 @@ public class StandardRoot extends LifecycleMBeanBase 
implements WebResourceRoot
             }
             if (f.isDirectory()) {
                 mainResourceSet = new DirResourceSet(this, "/", 
f.getAbsolutePath(), "/");
+                mainResourceSet.setReadOnly(readOnly);
             } else if (f.isFile() && docBase.endsWith(".war")) {
                 mainResourceSet = new WarResourceSet(this, "/", 
f.getAbsolutePath());
             } else {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 2d9b8bf288..07a2246f93 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -116,6 +116,13 @@
         Improve HTTP If headers processing according to RFC 9110. Based on pull
         request <pr>796</pr> by Chenjp. (remm/markt)
       </update>
+      <update>
+        Allow <code>readOnly</code> attribute configuration on the
+        <code>Resources</code> element and allow configure the
+        <code>readOnly</code> attribute value of the main resources. The
+        attribute value will also be used by the default and WebDAV Servlets.
+        (remm)
+      </update>
     </changelog>
   </subsection>
   <subsection name="Coyote">
diff --git a/webapps/docs/config/resources.xml 
b/webapps/docs/config/resources.xml
index 4bad617355..ef6a3aec37 100644
--- a/webapps/docs/config/resources.xml
+++ b/webapps/docs/config/resources.xml
@@ -122,6 +122,12 @@
         used.</p>
       </attribute>
 
+      <attribute name="readOnly" required="false">
+        <p>If the value of this flag is <code>true</code>, then writing will
+        be enabled on the main resource set. The default value is
+        <code>false</code>.</p>
+      </attribute>
+
       <attribute name="trackLockedFiles" required="false">
         <p>Controls whether the track locked files feature is enabled. If
         enabled, all calls to methods that return objects that lock a file and


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

Reply via email to