This is an automated email from the ASF dual-hosted git repository.

rmaucher 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 31d494b6eb Fix saving context in server.xml
31d494b6eb is described below

commit 31d494b6eb860bd6e25a82ae807c9e6c6e14f442
Author: remm <[email protected]>
AuthorDate: Wed Sep 2 21:41:54 2026 +0200

    Fix saving context in server.xml
    
    Not recommended but possible.
    Avoid duplication and conflicts with some endpoint properties.
    Found by code review.
---
 .../storeconfig/ConnectorStoreAppender.java        | 22 +++++++++++++++++++++-
 .../catalina/storeconfig/LocalStrings.properties   |  1 +
 .../catalina/storeconfig/StandardContextSF.java    |  6 ++++++
 .../catalina/storeconfig/StoreContextAppender.java |  2 +-
 webapps/docs/changelog.xml                         |  4 ++++
 5 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/catalina/storeconfig/ConnectorStoreAppender.java 
b/java/org/apache/catalina/storeconfig/ConnectorStoreAppender.java
index 4e274aad33..e25e07d990 100644
--- a/java/org/apache/catalina/storeconfig/ConnectorStoreAppender.java
+++ b/java/org/apache/catalina/storeconfig/ConnectorStoreAppender.java
@@ -24,6 +24,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -67,6 +68,12 @@ public class ConnectorStoreAppender extends StoreAppender {
         super();
     }
 
+    /**
+     * Map of attribute names stored in the socket properties but present as 
properties on the endpoint.
+     */
+    protected static final Set<String> derivedEndpointAttributes =
+            new HashSet<>(Arrays.asList("connectionTimeout", 
"connectionLinger"));
+
     /**
      * Map of attribute name replacements for connector properties.
      */
@@ -184,6 +191,10 @@ public class ConnectorStoreAppender extends StoreAppender {
                     internalExecutorAttributes.contains(key)) {
                 continue;
             }
+            // Avoid duplicating properties, so properties saved to the socket 
will be saved there
+            if (derivedEndpointAttributes.contains(key)) {
+                continue;
+            }
             if (replacements.get(key) != null) {
                 key = replacements.get(key);
             }
@@ -278,7 +289,16 @@ public class ConnectorStoreAppender extends StoreAppender {
                 File catalinaBase = getCatalinaBase();
                 File jkHomeBase = getJkHomeBase((String) 
connector.getProperty("jkHome"), catalinaBase);
                 isPrint = !catalinaBase.equals(jkHomeBase);
-
+            } else if ("keepAliveTimeout".equals(attrName)) {
+                /*
+                 * When keepAliveTimeout has not been explicitly configured, 
the endpoint reports the value of
+                 * connectionTimeout. Storing that derived value would 
duplicate the connectionTimeout configuration, so
+                 * suppress it unless it differs from connectionTimeout.
+                 */
+                Object keepAliveTimeout = IntrospectionUtils.getProperty(bean, 
"keepAliveTimeout");
+                Object connectionTimeout = 
IntrospectionUtils.getProperty(bean, "connectionTimeout");
+                isPrint = (keepAliveTimeout == null) || (connectionTimeout == 
null) ||
+                        !keepAliveTimeout.equals(connectionTimeout);
             }
         }
         return isPrint;
diff --git a/java/org/apache/catalina/storeconfig/LocalStrings.properties 
b/java/org/apache/catalina/storeconfig/LocalStrings.properties
index 1befcfc471..874e4de2b7 100644
--- a/java/org/apache/catalina/storeconfig/LocalStrings.properties
+++ b/java/org/apache/catalina/storeconfig/LocalStrings.properties
@@ -39,6 +39,7 @@ standardContextSF.canonicalPathError=Failed to obtain the 
canonical path of the
 standardContextSF.moveFailed=Context original file at [{0}] is null, not a 
file or not writable
 standardContextSF.nonFileConfigUrl=The config URL [{0}] is not file based
 standardContextSF.storeContext=Store context [{0}] configuration separately at 
path [{1}]
+standardContextSF.storeContextSkipped=Context [{0}] not stored because 
external context storage is not allowed and no writer for server.xml is 
available
 standardContextSF.storeContextWithBackup=Store context [{0}] configuration 
separately with backup at path [{1}]
 
 storeConfigListener.loadError=Error loading StoreConfig
diff --git a/java/org/apache/catalina/storeconfig/StandardContextSF.java 
b/java/org/apache/catalina/storeconfig/StandardContextSF.java
index de30be7e4f..95450b65c1 100644
--- a/java/org/apache/catalina/storeconfig/StandardContextSF.java
+++ b/java/org/apache/catalina/storeconfig/StandardContextSF.java
@@ -86,6 +86,12 @@ public class StandardContextSF extends StoreFactoryBase {
                             storeContextSeparate(aWriter, indent, 
(StandardContext) aContext);
                         }
                         return;
+                    } else if (aWriter == null) {
+                        if (log.isInfoEnabled()) {
+                            
log.info(sm.getString("standardContextSF.storeContextSkipped",
+                                    ((StandardContext) aContext).getPath()));
+                        }
+                        return;
                     }
                 } else if (desc.isExternalOnly()) {
                     // Set a configFile so that the configuration is actually 
saved
diff --git a/java/org/apache/catalina/storeconfig/StoreContextAppender.java 
b/java/org/apache/catalina/storeconfig/StoreContextAppender.java
index b49e43f713..1896595b51 100644
--- a/java/org/apache/catalina/storeconfig/StoreContextAppender.java
+++ b/java/org/apache/catalina/storeconfig/StoreContextAppender.java
@@ -75,7 +75,7 @@ public class StoreContextAppender extends StoreAppender {
                     isPrint = !defaultWorkDir.equals(context.getWorkDir());
                 }
             } else if ("path".equals(attrName)) {
-                isPrint = desc.isStoreSeparate() && desc.isExternalAllowed() 
&& context.getConfigFile() == null;
+                isPrint = !desc.isStoreSeparate() || !desc.isExternalAllowed() 
|| context.getConfigFile() == null;
             } else if ("docBase".equals(attrName)) {
                 Container host = context.getParent();
                 if (host instanceof StandardHost) {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index b866342d18..98aee3e7d9 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -172,6 +172,10 @@
         explicitly use the canonical context path for the
         <code>CONTEXT_PATH</code> server variable. (markt)
       </fix>
+      <fix>
+        Fix storeconfig not saving the path when a context is saved in
+        server.xml. (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to