This is an automated email from the ASF dual-hosted git repository. dsoumis pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit bcf169fa9bddbe659899ef7330cbf400740d686e Author: Dimitris Soumis <jimsou...@gmail.com> AuthorDate: Mon Sep 8 15:37:22 2025 +0300 Test case for https://bz.apache.org/bugzilla/show_bug.cgi?id=57700 --- .../apache/catalina/manager/TestManagerWebapp.java | 114 +++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/test/org/apache/catalina/manager/TestManagerWebapp.java b/test/org/apache/catalina/manager/TestManagerWebapp.java index cfe4370bcd..bbe7e749e1 100644 --- a/test/org/apache/catalina/manager/TestManagerWebapp.java +++ b/test/org/apache/catalina/manager/TestManagerWebapp.java @@ -30,7 +30,12 @@ import org.junit.Assert; import org.junit.Test; import static org.apache.catalina.startup.SimpleHttpClient.CRLF; +import org.apache.catalina.Container; +import org.apache.catalina.ContainerListener; import org.apache.catalina.Context; +import org.apache.catalina.Lifecycle; +import org.apache.catalina.LifecycleEvent; +import org.apache.catalina.LifecycleListener; import org.apache.catalina.authenticator.TestBasicAuthParser.BasicAuthHeader; import org.apache.catalina.realm.MemoryRealm; import org.apache.catalina.realm.MessageDigestCredentialHandler; @@ -43,6 +48,7 @@ import org.apache.catalina.storeconfig.StoreConfigLifecycleListener; import org.apache.catalina.util.IOTools; import org.apache.catalina.util.URLEncoder; + public class TestManagerWebapp extends TomcatBaseTest { public static final String CONFIG = "<?xml version=\"1.0\" ?>" + @@ -500,5 +506,113 @@ public class TestManagerWebapp extends TomcatBaseTest { tomcat.stop(); } + /** + * Test case for <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=57700">Bug 57700</a>. + */ + @Test + public void testBug57700() throws Exception { + ignoreTearDown = true; + Tomcat tomcat = getTomcatInstance(); + tomcat.setAddDefaultWebXmlToWebapp(false); + File configFile = new File(getTemporaryDirectory(), "tomcat-users-manager-lifecycle.xml"); + try (PrintWriter writer = new PrintWriter(configFile)) { + writer.write(CONFIG); + } + addDeleteOnTearDown(configFile); + + MemoryRealm memoryRealm = new MemoryRealm(); + memoryRealm.setCredentialHandler(new MessageDigestCredentialHandler()); + memoryRealm.setPathname(configFile.getAbsolutePath()); + tomcat.getEngine().setRealm(memoryRealm); + + File webappDir = new File(getBuildDirectory(), "webapps"); + + File appDir = new File(webappDir, "manager"); + Context ctx = tomcat.addWebapp(null, "/manager", appDir.getAbsolutePath()); + + HostConfig hostConfig = new HostConfig(); + ctx.getParent().addLifecycleListener(hostConfig); + + ContainerListener containerListener = event -> { + if (Container.ADD_CHILD_EVENT.equals(event.getType())) { + Container child = (Container) event.getData(); + if (child instanceof Context c) { + if ("/examples".equals(c.getPath())) { + c.addLifecycleListener(new FailOnceListener()); + } + } + } + }; + ctx.getParent().addContainerListener(containerListener); + + tomcat.start(); + SimpleHttpClient client = new SimpleHttpClient() { + @Override + public void connect() throws UnknownHostException, IOException { + connect(30000, 30000); + } + + @Override + public boolean isResponseBodyOK() { + return true; + } + }; + + appDir = new File(webappDir, "examples"); + client.setPort(getPort()); + String basicHeader = (new BasicAuthHeader("Basic", "admin", "sekr3t")).getHeader().toString(); + + client.setRequest(new String[] { + "GET /manager/text/deploy?war=" + URLEncoder.QUERY.encode(appDir.getAbsolutePath(), StandardCharsets.UTF_8) + " HTTP/1.1" + CRLF + + "Host: localhost" + CRLF + + "Authorization: " + basicHeader + CRLF + + "Connection: Close" + CRLF + CRLF + }); + client.connect(); + client.processRequest(true); + Assert.assertEquals(HttpServletResponse.SC_OK, client.getStatusCode()); + + client.setRequest(new String[] { + "GET /examples/servlets/servlet/RequestInfoExample HTTP/1.1" + CRLF + + "Host: localhost" + CRLF + + "Connection: Close" + CRLF + CRLF + }); + client.connect(); + client.processRequest(true); + Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, client.getStatusCode()); + + client.setRequest(new String[] { + "GET /manager/text/start?path=/examples HTTP/1.1" + CRLF + + "Host: localhost" + CRLF + + "Authorization: " + basicHeader + CRLF + + "Connection: Close" + CRLF + CRLF + }); + client.connect(); + client.processRequest(true); + Assert.assertEquals(HttpServletResponse.SC_OK, client.getStatusCode()); + + client.setRequest(new String[] { + "GET /examples/servlets/servlet/RequestInfoExample HTTP/1.1" + CRLF + + "Host: localhost" + CRLF + + "Connection: Close" + CRLF + CRLF + }); + client.connect(); + client.processRequest(true); + Assert.assertEquals(HttpServletResponse.SC_OK, client.getStatusCode()); + + tomcat.stop(); + } + private static class FailOnceListener implements LifecycleListener { + private volatile boolean firstRun = true; + @Override + public void lifecycleEvent(LifecycleEvent event) { + if (event.getLifecycle() instanceof Context) { + if (Lifecycle.CONFIGURE_START_EVENT.equals(event.getType()) && firstRun) { + firstRun = false; + throw new RuntimeException("Configuration failure in first run only"); + } + } + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org