Added: tomcat/tc6.0.x/branches/tomcat6-testing_20160106/BRANCH-diff.diff URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/branches/tomcat6-testing_20160106/BRANCH-diff.diff?rev=1726112&view=auto ============================================================================== --- tomcat/tc6.0.x/branches/tomcat6-testing_20160106/BRANCH-diff.diff (added) +++ tomcat/tc6.0.x/branches/tomcat6-testing_20160106/BRANCH-diff.diff Thu Jan 21 21:55:19 2016 @@ -0,0 +1,3922 @@ +Index: test/build.xml +=================================================================== +--- test/build.xml (.../trunk) (revision 1726111) ++++ test/build.xml (.../branches/tomcat6-testing_20160106) (revision 1726111) +@@ -1,71 +0,0 @@ +-<?xml version="1.0"?> +-<!-- +- Licensed to the Apache Software Foundation (ASF) under one or more +- contributor license agreements. See the NOTICE file distributed with +- this work for additional information regarding copyright ownership. +- The ASF licenses this file to You under the Apache License, Version 2.0 +- (the "License"); you may not use this file except in compliance with +- the License. You may obtain a copy of the License at +- +- http://www.apache.org/licenses/LICENSE-2.0 +- +- Unless required by applicable law or agreed to in writing, software +- distributed under the License is distributed on an "AS IS" BASIS, +- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- See the License for the specific language governing permissions and +- limitations under the License. +---> +-<project name="Tomcat 6.0" default="all" basedir="."> +- +- <!-- See "build.properties.sample" in the top level directory for all --> +- <!-- property values you must customize for successful building!!! --> +- <property file="${user.home}/build.properties"/> +- <property file="build.properties"/> +- +- <property file="build.properties.default"/> +- +- <property name="test.classes" value="${basedir}/output/classes"/> +- <property name="tomcat.build" value="${basedir}/../output/build"/> +- +- <property name="compile.source" value="1.5"/> +- <property name="compile.debug" value="true"/> +- +- <property name="junit.jar" value="${junit.home}/junit.jar"/> +- <property name="test.runner" value="junit.textui.TestRunner"/> +- +- <path id="tomcat.test.classpath"> +- <pathelement location="${test.classes}"/> +- <pathelement location="${junit.jar}"/> +- <fileset dir="${tomcat.build}/lib/"> +- <include name="tomcat-coyote.jar"/> +- </fileset> +- <fileset dir="${tomcat.build}/bin/"> +- <include name="tomcat-juli.jar"/> +- </fileset> +- </path> +- +- <target name="compile"> +- +- <mkdir dir="${test.classes}"/> +- +- <!-- Compile --> +- <javac srcdir="." destdir="${test.classes}" +- debug="${compile.debug}" +- deprecation="${compile.deprecation}" +- source="${compile.source}" +- optimize="${compile.optimize}" +- encoding="ISO-8859-1"> +- <classpath refid="tomcat.test.classpath" /> +- <include name="org/apache/tomcat/util/**" /> +- </javac> +- +- </target> +- +- <target name="all" depends="compile"> +- <java dir="${test.classes}" classname="${test.runner}" fork="yes" failonerror="${test.failonerror}"> +- <arg value="org.apache.tomcat.util.http.TestCookies"/> +- <classpath refid="tomcat.test.classpath"/> +- </java> +- +- </target> +-</project> +Index: test/deployment/dirNoContext/index.html +=================================================================== +--- test/deployment/dirNoContext/index.html (.../trunk) (revision 0) ++++ test/deployment/dirNoContext/index.html (.../branches/tomcat6-testing_20160106) (revision 1726111) +@@ -0,0 +1,22 @@ ++<!-- ++ Licensed to the Apache Software Foundation (ASF) under one or more ++ contributor license agreements. See the NOTICE file distributed with ++ this work for additional information regarding copyright ownership. ++ The ASF licenses this file to You under the Apache License, Version 2.0 ++ (the "License"); you may not use this file except in compliance with ++ the License. You may obtain a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, ++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ See the License for the specific language governing permissions and ++ limitations under the License. ++--> ++<!-- dirNoContext --> ++<html> ++ <body> ++ <p>Directory based web application with no context.xml file.</p> ++ </body> ++</html> +\ No newline at end of file + +Property changes on: test/deployment/dirNoContext/index.html +___________________________________________________________________ +Added: svn:eol-style +## -0,0 +1 ## ++native +\ No newline at end of property +Index: test/deployment/dirContext/index.html +=================================================================== +--- test/deployment/dirContext/index.html (.../trunk) (revision 0) ++++ test/deployment/dirContext/index.html (.../branches/tomcat6-testing_20160106) (revision 1726111) +@@ -0,0 +1,22 @@ ++<!-- ++ Licensed to the Apache Software Foundation (ASF) under one or more ++ contributor license agreements. See the NOTICE file distributed with ++ this work for additional information regarding copyright ownership. ++ The ASF licenses this file to You under the Apache License, Version 2.0 ++ (the "License"); you may not use this file except in compliance with ++ the License. You may obtain a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, ++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ See the License for the specific language governing permissions and ++ limitations under the License. ++--> ++<!-- dirContext --> ++<html> ++ <body> ++ <p>Directory based web application with a context.xml file.</p> ++ </body> ++</html> +\ No newline at end of file + +Property changes on: test/deployment/dirContext/index.html +___________________________________________________________________ +Added: svn:eol-style +## -0,0 +1 ## ++native +\ No newline at end of property +Index: test/deployment/dirContext/META-INF/context.xml +=================================================================== +--- test/deployment/dirContext/META-INF/context.xml (.../trunk) (revision 0) ++++ test/deployment/dirContext/META-INF/context.xml (.../branches/tomcat6-testing_20160106) (revision 1726111) +@@ -0,0 +1,17 @@ ++<!-- ++ Licensed to the Apache Software Foundation (ASF) under one or more ++ contributor license agreements. See the NOTICE file distributed with ++ this work for additional information regarding copyright ownership. ++ The ASF licenses this file to You under the Apache License, Version 2.0 ++ (the "License"); you may not use this file except in compliance with ++ the License. You may obtain a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, ++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ See the License for the specific language governing permissions and ++ limitations under the License. ++--> ++<Context sessionCookieName="DIR_CONTEXT" /> +\ No newline at end of file + +Property changes on: test/deployment/dirContext/META-INF/context.xml +___________________________________________________________________ +Added: svn:eol-style +## -0,0 +1 ## ++native +\ No newline at end of property +Index: test/org/apache/catalina/connector/TestConnector.java +=================================================================== +--- test/org/apache/catalina/connector/TestConnector.java (.../trunk) (revision 0) ++++ test/org/apache/catalina/connector/TestConnector.java (.../branches/tomcat6-testing_20160106) (revision 1726111) +@@ -0,0 +1,44 @@ ++/* ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++package org.apache.catalina.connector; ++ ++import org.junit.Test; ++ ++import static org.junit.Assert.assertTrue; ++ ++import org.apache.catalina.startup.Tomcat; ++import org.apache.catalina.startup.TomcatBaseTest; ++ ++/** ++ * Test cases for {@link Connector}. ++ */ ++public class TestConnector extends TomcatBaseTest { ++ ++ @Test ++ public void testPort() throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ ++ Connector connector1 = tomcat.getConnector(); ++ connector1.setPort(0); ++ ++ tomcat.start(); ++ ++ int localPort1 = connector1.getLocalPort(); ++ ++ assertTrue(localPort1 > 0); ++ } ++} + +Property changes on: test/org/apache/catalina/connector/TestConnector.java +___________________________________________________________________ +Added: svn:eol-style +## -0,0 +1 ## ++native +\ No newline at end of property +Index: test/org/apache/catalina/startup/TestTomcat.java +=================================================================== +--- test/org/apache/catalina/startup/TestTomcat.java (.../trunk) (revision 0) ++++ test/org/apache/catalina/startup/TestTomcat.java (.../branches/tomcat6-testing_20160106) (revision 1726111) +@@ -0,0 +1,594 @@ ++/* ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++package org.apache.catalina.startup; ++ ++import java.io.File; ++import java.io.IOException; ++import java.io.InputStream; ++import java.io.InputStreamReader; ++import java.io.Reader; ++import java.net.URL; ++import java.net.URLConnection; ++import java.util.concurrent.atomic.AtomicInteger; ++ ++import javax.naming.InitialContext; ++import javax.naming.NamingException; ++import javax.servlet.ServletException; ++import javax.servlet.http.HttpServlet; ++import javax.servlet.http.HttpServletRequest; ++import javax.servlet.http.HttpServletResponse; ++import javax.servlet.http.HttpSession; ++ ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.assertNotNull; ++import static org.junit.Assert.assertNull; ++import static org.junit.Assert.assertTrue; ++import static org.junit.Assert.fail; ++ ++import org.junit.Test; ++ ++import org.apache.catalina.Context; ++import org.apache.catalina.Host; ++import org.apache.catalina.core.StandardContext; ++import org.apache.catalina.core.StandardHost; ++import org.apache.catalina.deploy.ContextEnvironment; ++import org.apache.catalina.deploy.ContextResourceLink; ++import org.apache.catalina.ha.context.ReplicatedContext; ++import org.apache.tomcat.util.buf.ByteChunk; ++ ++public class TestTomcat extends TomcatBaseTest { ++ ++ /** ++ * Simple servlet to test in-line registration. ++ */ ++ public static class HelloWorld extends HttpServlet { ++ ++ private static final long serialVersionUID = 1L; ++ ++ @Override ++ public void doGet(HttpServletRequest req, HttpServletResponse res) ++ throws IOException { ++ res.getWriter().write("Hello world"); ++ } ++ } ++ ++ /** ++ * Simple servlet to test the default session manager. ++ */ ++ public static class HelloWorldSession extends HttpServlet { ++ ++ private static final long serialVersionUID = 1L; ++ ++ @Override ++ public void doGet(HttpServletRequest req, HttpServletResponse res) ++ throws IOException { ++ HttpSession s = req.getSession(true); ++ s.getId(); ++ res.getWriter().write("Hello world"); ++ } ++ } ++ ++ /** ++ * Simple servlet to test JNDI ++ */ ++ public static class HelloWorldJndi extends HttpServlet { ++ ++ private static final long serialVersionUID = 1L; ++ ++ private static final String JNDI_ENV_NAME = "test"; ++ ++ @Override ++ public void doGet(HttpServletRequest req, HttpServletResponse res) ++ throws IOException { ++ ++ String name = null; ++ ++ try { ++ javax.naming.Context initCtx = new InitialContext(); ++ javax.naming.Context envCtx = ++ (javax.naming.Context) initCtx.lookup("java:comp/env"); ++ name = (String) envCtx.lookup(JNDI_ENV_NAME); ++ } catch (NamingException e) { ++ IOException ioe = new IOException(e.getMessage()); ++ ioe.initCause(e); ++ throw ioe; ++ } ++ ++ res.getWriter().write("Hello, " + name); ++ } ++ } ++ ++ /** ++ * Servlet that tries to obtain a URL for WEB-INF/web.xml ++ */ ++ public static class GetResource extends HttpServlet { ++ ++ private static final long serialVersionUID = 1L; ++ ++ @Override ++ public void doGet(HttpServletRequest req, HttpServletResponse res) ++ throws IOException { ++ URL url = getServletContext().getResource("/WEB-INF/web.xml"); ++ ++ res.getWriter().write("The URL obtained for /WEB-INF/web.xml was "); ++ if (url == null) { ++ res.getWriter().write("null"); ++ } else { ++ res.getWriter().write(url.toString() + "\n"); ++ res.getWriter().write("The first 20 characters of that resource are:\n"); ++ ++ // Read some content from the resource ++ URLConnection conn = url.openConnection(); ++ ++ InputStream is = null; ++ Reader reader = null; ++ char cbuf[] = new char[20]; ++ int read = 0; ++ try { ++ is = conn.getInputStream(); ++ reader = new InputStreamReader(is); ++ while (read < 20) { ++ int len = reader.read(cbuf, read, cbuf.length - read); ++ res.getWriter().write(cbuf, read, len); ++ read = read + len; ++ } ++ } finally { ++ if (reader != null) { ++ try { reader.close(); } catch(IOException ioe) {/*Ignore*/} ++ } ++ if (is != null) { ++ try { is.close(); } catch(IOException ioe) {/*Ignore*/} ++ } ++ } ++ ++ ++ } ++ ++ ++ } ++ } ++ ++ /** ++ * Simple servlet to test initialization of servlet instances. ++ */ ++ private static class InitCount extends HttpServlet { ++ ++ private static final long serialVersionUID = 1L; ++ ++ private AtomicInteger callCount = new AtomicInteger(0); ++ ++ @Override ++ public void init() throws ServletException { ++ super.init(); ++ callCount.incrementAndGet(); ++ } ++ ++ @Override ++ protected void doGet(HttpServletRequest req, HttpServletResponse resp) ++ throws ServletException, IOException { ++ resp.setContentType("text/plain"); ++ resp.getWriter().print("OK"); ++ } ++ ++ public int getCallCount() { ++ return callCount.intValue(); ++ } ++ } ++ ++ ++// /** ++// * Simple Realm that uses a configurable {@link Map} to link user names and ++// * passwords. ++// */ ++// public static final class MapRealm extends RealmBase { ++// private Map<String,String> users = new HashMap<String,String>(); ++// private Map<String,List<String>> roles = ++// new HashMap<String,List<String>>(); ++// ++// public void addUser(String username, String password) { ++// users.put(username, password); ++// } ++// ++// public void addUserRole(String username, String role) { ++// List<String> userRoles = roles.get(username); ++// if (userRoles == null) { ++// userRoles = new ArrayList<String>(); ++// roles.put(username, userRoles); ++// } ++// userRoles.add(role); ++// } ++// ++// @Override ++// protected String getName() { ++// return "MapRealm"; ++// } ++// ++// @Override ++// protected String getPassword(String username) { ++// return users.get(username); ++// } ++// ++// @Override ++// protected Principal getPrincipal(String username) { ++// return new GenericPrincipal(username, getPassword(username), ++// roles.get(username)); ++// } ++// ++// } ++ ++ /** ++ * Start tomcat with a single context and one ++ * servlet - all programmatic, no server.xml or ++ * web.xml used. ++ * ++ * @throws Exception ++ */ ++ @Test ++ public void testProgrammatic() throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ ++ // No file system docBase required ++ Context ctx = tomcat.addContext("", null); ++ ++ // You can customize the context by calling ++ // its API ++ ++ Tomcat.addServlet(ctx, "myServlet", new HelloWorld()); ++ ctx.addServletMapping("/", "myServlet"); ++ ++ tomcat.start(); ++ ++ ByteChunk res = getUrl("http://localhost:" + getPort() + "/"); ++ assertEquals("Hello world", res.toString()); ++ } ++ ++ @Test ++ public void testSingleWebapp() throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ ++ File appDir = new File(getBuildDirectory(), "webapps/examples"); ++ ++ tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); ++ ++ tomcat.start(); ++ ++ ByteChunk res = getUrl("http://localhost:" + getPort() + ++ "/examples/servlets/servlet/HelloWorldExample"); ++ String text = res.toString(); ++ assertTrue(text, text.indexOf("<h1>Hello World!</h1>") > 0); ++ } ++ ++ @Test ++ public void testJsps() throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ ++ File appDir = new File(getBuildDirectory(), "webapps/examples"); ++ // app dir is relative to server home ++ tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); ++ ++ tomcat.start(); ++ ++ ByteChunk res = getUrl("http://localhost:" + getPort() + ++ "/examples/jsp/jsp2/el/basic-arithmetic.jsp"); ++ String text = res.toString(); ++ assertTrue(text, text.indexOf("<td>${(1==2) ? 3 : 4}</td>") > 0); ++ } ++ ++ @Test ++ public void testSession() throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ ++ // No file system docBase required ++ Context ctx = tomcat.addContext("", null); ++ // You can customize the context by calling ++ // its API ++ ++ Tomcat.addServlet(ctx, "myServlet", new HelloWorldSession()); ++ ctx.addServletMapping("/", "myServlet"); ++ ++ tomcat.start(); ++ ++ ByteChunk res = getUrl("http://localhost:" + getPort() + "/"); ++ assertEquals("Hello world", res.toString()); ++ } ++ ++ @Test ++ public void testLaunchTime() throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ long t0 = System.currentTimeMillis(); ++ tomcat.addContext(null, "", "."); ++ tomcat.start(); ++ log.info("Tomcat started in [" + (System.currentTimeMillis() - t0) ++ + "] ms"); ++ } ++ ++ ++ /** ++ * Test for enabling JNDI. ++ */ ++ @Test ++ public void testEnableNaming() throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ ++ // No file system docBase required ++ Context ctx = tomcat.addContext("", null); ++ ++ // You can customise the context by calling its API ++ ++ // Enable JNDI - it is disabled by default ++ tomcat.enableNaming(); ++ ++ ContextEnvironment environment = new ContextEnvironment(); ++ environment.setType("java.lang.String"); ++ environment.setName(HelloWorldJndi.JNDI_ENV_NAME); ++ environment.setValue("Tomcat User"); ++ ctx.getNamingResources().addEnvironment(environment); ++ ++ Tomcat.addServlet(ctx, "jndiServlet", new HelloWorldJndi()); ++ ctx.addServletMapping("/", "jndiServlet"); ++ ++ tomcat.start(); ++ ++ ByteChunk res = getUrl("http://localhost:" + getPort() + "/"); ++ assertEquals("Hello, Tomcat User", res.toString()); ++ } ++ ++ /** ++ * Test for enabling JNDI and using global resources. ++ */ ++ @Test ++ public void testEnableNamingGlobal() throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ ++ // No file system docBase required ++ Context ctx = tomcat.addContext("", null); ++ ++ // You can customise the context by calling its API ++ ++ // Enable JNDI - it is disabled by default ++ tomcat.enableNaming(); ++ ++ ContextEnvironment environment = new ContextEnvironment(); ++ environment.setType("java.lang.String"); ++ environment.setName("globalTest"); ++ environment.setValue("Tomcat User"); ++ tomcat.getServer().getGlobalNamingResources().addEnvironment(environment); ++ ++ ContextResourceLink link = new ContextResourceLink(); ++ link.setGlobal("globalTest"); ++ link.setName(HelloWorldJndi.JNDI_ENV_NAME); ++ ctx.getNamingResources().addResourceLink(link); ++ ++ Tomcat.addServlet(ctx, "jndiServlet", new HelloWorldJndi()); ++ ctx.addServletMapping("/", "jndiServlet"); ++ ++ tomcat.start(); ++ ++ ByteChunk res = getUrl("http://localhost:" + getPort() + "/"); ++ assertEquals("Hello, Tomcat User", res.toString()); ++ } ++ ++ ++ /** ++ * Test for https://bz.apache.org/bugzilla/show_bug.cgi?id=47866 ++ */ ++ @Test ++ public void testGetResource() throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ ++ String contextPath = "/examples"; ++ ++ File appDir = new File(getBuildDirectory(), "webapps" + contextPath); ++ // app dir is relative to server home ++ Context ctx = ++ tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); ++ ++ Tomcat.addServlet(ctx, "testGetResource", new GetResource()); ++ ctx.addServletMapping("/testGetResource", "testGetResource"); ++ ++ tomcat.start(); ++ ++ ByteChunk res = new ByteChunk(); ++ ++ int rc =getUrl("http://localhost:" + getPort() + contextPath + ++ "/testGetResource", res, null); ++ assertEquals(HttpServletResponse.SC_OK, rc); ++ assertTrue(res.toString().contains("<?xml version=\"1.0\" ")); ++ } ++ ++ @Test ++ public void testBug50826() throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ String contextPath = "/examples"; ++ ++ File appDir = new File(getBuildDirectory(), "webapps" + contextPath); ++ // app dir is relative to server home ++ tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); ++ ++ Exception e = null; ++ try { ++ tomcat.destroy(); ++ } catch (Exception ex) { ++ ex.printStackTrace(); ++ e = ex; ++ } ++ assertNull(e); ++ } ++ ++ @Test ++ public void testBug53301() throws Exception { ++ Tomcat tomcat = getTomcatInstance(); ++ ++ // No file system docBase required ++ Context ctx = tomcat.addContext("", null); ++ ++ InitCount initCount = new InitCount(); ++ Tomcat.addServlet(ctx, "initCount", initCount); ++ ctx.addServletMapping("/", "initCount"); ++ ++ tomcat.start(); ++ ++ ByteChunk res = getUrl("http://localhost:" + getPort() + "/"); ++ assertEquals("OK", res.toString()); ++ ++ assertEquals(1, initCount.getCallCount()); ++ } ++ ++ @Test ++ public void testGetWebappConfigFileFromDirectory() { ++ Tomcat tomcat = new Tomcat(); ++ assertNotNull(tomcat.getWebappConfigFile("test/deployment/dirContext", "")); ++ } ++ ++ @Test ++ public void testGetWebappConfigFileFromDirectoryNegative() { ++ Tomcat tomcat = new Tomcat(); ++ assertNull(tomcat.getWebappConfigFile("test/deployment/dirNoContext", "")); ++ } ++ ++// Reading context.xml from a war file without copying it ++// is not implemented in Tomcat 6. (BZ 48662, r928380) ++// @Test ++// public void testGetWebappConfigFileFromJar() { ++// Tomcat tomcat = new Tomcat(); ++// assertNotNull(tomcat.getWebappConfigFile("test/deployment/context.war", "")); ++// } ++// ++// @Test ++// public void testGetWebappConfigFileFromJarNegative() { ++// Tomcat tomcat = new Tomcat(); ++// assertNull(tomcat.getWebappConfigFile("test/deployment/noContext.war", "")); ++// } ++// ++// @Test ++// public void testBug51526() throws Exception { ++// Tomcat tomcat = getTomcatInstance(); ++// ++// File appFile = new File("test/deployment/context.war"); ++// StandardContext context = (StandardContext) tomcat.addWebapp(null, "/test", ++// appFile.getAbsolutePath()); ++// ++// tomcat.start(); ++// ++// assertEquals("WAR_CONTEXT", context.getSessionCookieName()); ++// } ++// ++// @Test ++// public void testGetDefaultContextPerAddWebapp() { ++// Tomcat tomcat = getTomcatInstance(); ++// ++// File appFile = new File("test/deployment/context.war"); ++// Context context = tomcat.addWebapp(null, ++// "/test", appFile.getAbsolutePath()); ++// ++// assertEquals(StandardContext.class.getName(), context.getClass() ++// .getName()); ++// } ++// ++// @Test ++// public void testGetBrokenContextPerAddWepapp() { ++// Tomcat tomcat = getTomcatInstance(); ++// Host host = tomcat.getHost(); ++// if (host instanceof StandardHost) { ++// ((StandardHost) host).setContextClass("InvalidContextClassName"); ++// } ++// ++// try { ++// File appFile = new File("test/deployment/context.war"); ++// tomcat.addWebapp(null, "/test", appFile.getAbsolutePath()); ++// fail(); ++// } catch (IllegalArgumentException e) { ++// // OK ++// } ++// } ++// ++// @Test ++// public void testGetCustomContextPerAddWebappWithNullHost() { ++// Tomcat tomcat = getTomcatInstance(); ++// Host host = tomcat.getHost(); ++// if (host instanceof StandardHost) { ++// ((StandardHost) host).setContextClass(ReplicatedContext.class ++// .getName()); ++// } ++// ++// File appFile = new File("test/deployment/context.war"); ++// Context context = tomcat.addWebapp(null, "/test", ++// appFile.getAbsolutePath()); ++// ++// assertEquals(ReplicatedContext.class.getName(), context.getClass() ++// .getName()); ++// } ++// ++// @Test ++// public void testGetCustomContextPerAddWebappWithHost() { ++// Tomcat tomcat = getTomcatInstance(); ++// Host host = tomcat.getHost(); ++// if (host instanceof StandardHost) { ++// ((StandardHost) host).setContextClass(ReplicatedContext.class ++// .getName()); ++// } ++// ++// File appFile = new File("test/deployment/context.war"); ++// Context context = tomcat.addWebapp(host, "/test", ++// appFile.getAbsolutePath()); ++// ++// assertEquals(ReplicatedContext.class.getName(), context.getClass() ++// .getName()); ++// } ++ ++ @Test ++ public void testGetDefaultContextPerAddContext() { ++ Tomcat tomcat = getTomcatInstance(); ++ ++ // No file system docBase required ++ Context ctx = tomcat.addContext(null, "", null); ++ assertEquals(StandardContext.class.getName(), ctx.getClass().getName()); ++ } ++ ++ @Test ++ public void testGetBrokenContextPerAddContext() { ++ Tomcat tomcat = getTomcatInstance(); ++ Host host = tomcat.getHost(); ++ if (host instanceof StandardHost) { ++ ((StandardHost) host).setContextClass("InvalidContextClassName"); ++ } ++ ++ // No file system docBase required ++ try { ++ tomcat.addContext(null, "", null); ++ fail(); ++ } catch (IllegalArgumentException e) { ++ // OK ++ } ++ } ++ ++ @Test ++ public void testGetCustomContextPerAddContextWithHost() { ++ Tomcat tomcat = getTomcatInstance(); ++ Host host = tomcat.getHost(); ++ if (host instanceof StandardHost) { ++ ((StandardHost) host).setContextClass(ReplicatedContext.class ++ .getName()); ++ } ++ ++ // No file system docBase required ++ Context ctx = tomcat.addContext(host, "", null); ++ assertEquals(ReplicatedContext.class.getName(), ctx.getClass() ++ .getName()); ++ } ++ ++} + +Property changes on: test/org/apache/catalina/startup/TestTomcat.java +___________________________________________________________________ +Added: svn:eol-style +## -0,0 +1 ## ++native +\ No newline at end of property +Index: test/org/apache/catalina/startup/Tomcat.java +=================================================================== +--- test/org/apache/catalina/startup/Tomcat.java (.../trunk) (revision 0) ++++ test/org/apache/catalina/startup/Tomcat.java (.../branches/tomcat6-testing_20160106) (revision 1726111) +@@ -0,0 +1,1207 @@ ++/* ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++package org.apache.catalina.startup; ++ ++import java.io.File; ++import java.io.IOException; ++import java.lang.reflect.InvocationTargetException; ++import java.util.Stack; ++ ++import javax.servlet.Servlet; ++import javax.servlet.ServletException; ++ ++import org.apache.catalina.Container; ++import org.apache.catalina.Context; ++import org.apache.catalina.Engine; ++import org.apache.catalina.Globals; ++import org.apache.catalina.Host; ++import org.apache.catalina.Lifecycle; ++import org.apache.catalina.LifecycleEvent; ++import org.apache.catalina.LifecycleException; ++import org.apache.catalina.LifecycleListener; ++import org.apache.catalina.Server; ++import org.apache.catalina.Service; ++import org.apache.catalina.Wrapper; ++import org.apache.catalina.connector.Connector; ++import org.apache.catalina.core.NamingContextListener; ++import org.apache.catalina.core.StandardContext; ++import org.apache.catalina.core.StandardEngine; ++import org.apache.catalina.core.StandardHost; ++import org.apache.catalina.core.StandardServer; ++import org.apache.catalina.core.StandardService; ++import org.apache.catalina.core.StandardWrapper; ++ ++// TODO: lazy init for the temp dir - only when a JSP is compiled or ++// get temp dir is called we need to create it. This will avoid the ++// need for the baseDir ++ ++// TODO: allow contexts without a base dir - i.e. ++// only programmatic. This would disable the default servlet. ++ ++/** ++ * Minimal tomcat starter for embedding/unit tests. ++ * ++ * Tomcat supports multiple styles of configuration and ++ * startup - the most common and stable is server.xml-based, ++ * implemented in org.apache.catalina.startup.Bootstrap. ++ * ++ * This class is for use in apps that embed tomcat. ++ * Requirements: ++ * ++ * - all tomcat classes and possibly servlets are in the classpath. ++ * ( for example all is in one big jar, or in eclipse CP, or in any other ++ * combination ) ++ * ++ * - we need one temporary directory for work files ++ * ++ * - no config file is required. This class provides methods to ++ * use if you have a webapp with a web.xml file, but it is ++ * optional - you can use your own servlets. ++ * ++ * There are a variety of 'add' methods to configure servlets and webapps. These ++ * methods, by default, create a simple in-memory security realm and apply it. ++ * If you need more complex security processing, you can define a subclass of ++ * this class. ++ * ++ * This class provides a set of convenience methods for configuring webapp ++ * contexts, all overloads of the method <pre>addWebapp</pre>. These methods ++ * create a webapp context, configure it, and then add it to a {@link Host}. ++ * They do not use a global default web.xml; rather, they add a lifecycle ++ * listener that adds the standard DefaultServlet, JSP processing, and welcome ++ * files. ++ * ++ * In complex cases, you may prefer to use the ordinary Tomcat API to create ++ * webapp contexts; for example, you might need to install a custom Loader ++ * before the call to {@link Host#addChild(Container)}. To replicate the basic ++ * behavior of the <pre>addWebapp</pre> methods, you may want to call two ++ * methods of this class: {@link #noDefaultWebXmlPath()} and ++ * {@link #getDefaultWebXmlListener()}. ++ * ++ * {@link #getDefaultRealm()} returns the simple security realm. ++ * ++ * {@link #getDefaultWebXmlListener()} returns a {@link LifecycleListener} that ++ * adds the standard DefaultServlet, JSP processing, and welcome files. If you ++ * add this listener, you must prevent Tomcat from applying any standard global ++ * web.xml with ... ++ * ++ * {@link #noDefaultWebXmlPath()} returns a dummy pathname to configure to ++ * prevent {@link ContextConfig} from trying to apply a global web.xml file. ++ * ++ * This class provides a main() and few simple CLI arguments, ++ * see setters for doc. It can be used for simple tests and ++ * demo. ++ * ++ * @see <a href="http://svn.apache.org/repos/asf/tomcat/trunk/test/org/apache/catalina/startup/TestTomcat.java">TestTomcat</a> ++ * @author Costin Manolache ++ */ ++public class Tomcat { ++ ++// // Some logging implementations use weak references for loggers so there is ++// // the possibility that logging configuration could be lost if GC runs just ++// // after Loggers are configured but before they are used. The purpose of ++// // this Map is to retain strong references to explicitly configured loggers ++// // so that configuration is not lost. ++// private final Map<String, Logger> pinnedLoggers = new HashMap<String, Logger>(); ++ ++ // Single engine, service, server, connector - few cases need more, ++ // they can use server.xml ++ protected StandardServer server; ++ protected StandardService service; ++ protected StandardEngine engine; ++ protected Connector connector; // for more - customize the classes ++ ++ // To make it a bit easier to config for the common case ++ // ( one host, one context ). ++ protected Host host; ++ ++ // TODO: it's easy to add support for more hosts - but is it ++ // really needed ? ++ ++ // TODO: allow use of in-memory connector ++ ++ protected int port = 8080; ++ protected String hostname = "localhost"; ++ protected String basedir; ++ ++ private volatile boolean initialized; ++ private volatile boolean started; ++ ++// // Default in-memory realm, will be set by default on the Engine. Can be ++// // replaced at engine level or over-ridden at Host or Context level ++// @Deprecated // Will be removed in Tomcat 8.0.x. ++// protected Realm defaultRealm; ++// private final Map<String, String> userPass = new HashMap<String, String>(); ++// private final Map<String, List<String>> userRoles = ++// new HashMap<String, List<String>>(); ++// private final Map<String, Principal> userPrincipals = ++// new HashMap<String, Principal>(); ++ ++ public Tomcat() { ++ // NOOP ++ } ++ ++ /** ++ * Tomcat needs a directory for temp files. This should be the ++ * first method called. ++ * ++ * By default, if this method is not called, we use: ++ * - system properties - catalina.base, catalina.home ++ * - $HOME/tomcat.$PORT ++ * ( /tmp doesn't seem a good choice for security ). ++ * ++ * ++ * TODO: better default ? Maybe current dir ? ++ * TODO: disable work dir if not needed ( no jsp, etc ). ++ */ ++ public void setBaseDir(String basedir) { ++ this.basedir = basedir; ++ } ++ ++ /** ++ * Set the port for the default connector. Must ++ * be called before start(). ++ */ ++ public void setPort(int port) { ++ this.port = port; ++ } ++ ++ /** ++ * The the hostname of the default host, default is ++ * 'localhost'. ++ */ ++ public void setHostname(String s) { ++ hostname = s; ++ } ++ ++ /** ++ * This is equivalent to adding a web application to Tomcat's webapps ++ * directory. The equivalent of the default web.xml will be applied to the ++ * web application and any WEB-INF/web.xml and META-INF/context.xml packaged ++ * with the application will be processed normally. Normal web fragment and ++ * {@link javax.servlet.ServletContainerInitializer} processing will be ++ * applied. ++ * ++ * @throws ServletException ++ */ ++ public Context addWebapp(String contextPath, String docBase) throws ServletException { ++ return addWebapp(getHost(), contextPath, docBase); ++ } ++ ++ ++ /** ++ * Add a context - programmatic mode, no web.xml used. ++ * ++ * API calls equivalent with web.xml: ++ * ++ * context-param ++ * ctx.addParameter("name", "value"); ++ * ++ * ++ * error-page ++ * ErrorPage ep = new ErrorPage(); ++ * ep.setErrorCode(500); ++ * ep.setLocation("/error.html"); ++ * ctx.addErrorPage(ep); ++ * ++ * ctx.addMimeMapping("ext", "type"); ++ * ++ * Note: If you reload the Context, all your configuration will be lost. If ++ * you need reload support, consider using a LifecycleListener to provide ++ * your configuration. ++ * ++ * TODO: add the rest ++ * ++ * @param contextPath "" for root context. ++ * @param docBase base dir for the context, for static files. Must exist, ++ * relative to the server home ++ */ ++ public Context addContext(String contextPath, String docBase) { ++ return addContext(getHost(), contextPath, docBase); ++ } ++ ++// /** ++// * Equivalent with ++// * <servlet><servlet-name><servlet-class>. ++// * ++// * In general it is better/faster to use the method that takes a ++// * Servlet as param - this one can be used if the servlet is not ++// * commonly used, and want to avoid loading all deps. ++// * ( for example: jsp servlet ) ++// * ++// * You can customize the returned servlet, ex: ++// * ++// * wrapper.addInitParameter("name", "value"); ++// * ++// * @param contextPath Context to add Servlet to ++// * @param servletName Servlet name (used in mappings) ++// * @param servletClass The class to be used for the Servlet ++// * @return The wrapper for the servlet ++// */ ++// public Wrapper addServlet(String contextPath, ++// String servletName, ++// String servletClass) { ++// Container ctx = getHost().findChild(contextPath); ++// return addServlet((Context) ctx, servletName, servletClass); ++// } ++ ++ /** ++ * Static version of {@link #addServlet(String, String, String)} ++ * @param ctx Context to add Servlet to ++ * @param servletName Servlet name (used in mappings) ++ * @param servletClass The class to be used for the Servlet ++ * @return The wrapper for the servlet ++ */ ++ public static Wrapper addServlet(Context ctx, ++ String servletName, ++ String servletClass) { ++ // will do class for name and set init params ++ Wrapper sw = ctx.createWrapper(); ++ sw.setServletClass(servletClass); ++ sw.setName(servletName); ++ ctx.addChild(sw); ++ ++ return sw; ++ } ++ ++// /** ++// * Add an existing Servlet to the context with no class.forName or ++// * initialisation. ++// * @param contextPath Context to add Servlet to ++// * @param servletName Servlet name (used in mappings) ++// * @param servlet The Servlet to add ++// * @return The wrapper for the servlet ++// */ ++// public Wrapper addServlet(String contextPath, ++// String servletName, ++// Servlet servlet) { ++// Container ctx = getHost().findChild(contextPath); ++// return addServlet((Context) ctx, servletName, servlet); ++// } ++ ++ /** ++ * Static version of {@link #addServlet(String, String, Servlet)}. ++ * @param ctx Context to add Servlet to ++ * @param servletName Servlet name (used in mappings) ++ * @param servlet The Servlet to add ++ * @return The wrapper for the servlet ++ */ ++ public static Wrapper addServlet(Context ctx, ++ String servletName, ++ Servlet servlet) { ++ // will do class for name and set init params ++ Wrapper sw = new ExistingStandardWrapper(servlet); ++ sw.setName(servletName); ++ ctx.addChild(sw); ++ ++ return sw; ++ } ++ ++ ++ /** ++ * Initialise the server. ++ * ++ * @throws LifecycleException ++ */ ++ public void init() throws LifecycleException { ++ getServer(); ++ getConnector(); ++ if (!initialized) { ++ initialized = true; ++ try { ++ server.init(); ++ } catch (LifecycleException e) { ++ throw e; ++ } catch (Exception e) { ++ throw new LifecycleException(e); ++ } ++ } ++ } ++ ++ ++ /** ++ * Start the server. ++ * ++ * @throws LifecycleException ++ */ ++ public void start() throws LifecycleException { ++ if (!started) { ++ init(); ++ started = true; ++ server.start(); ++ } ++ } ++ ++ /** ++ * Stop the server. ++ * ++ * @throws LifecycleException ++ */ ++ public void stop() throws LifecycleException { ++ if (started) { ++ started = false; ++ server.stop(); ++ } ++ } ++ ++ ++ /** ++ * Destroy the server. This object cannot be used once this method has been ++ * called. ++ */ ++ public void destroy() throws LifecycleException { ++ if (initialized) { ++ stop(); ++ initialized = false; ++ // server.destroy(); ++ // Could null out objects here ++ } ++ } ++ ++// /** ++// * Add a user for the in-memory realm. All created apps use this ++// * by default, can be replaced using setRealm(). ++// * ++// */ ++// public void addUser(String user, String pass) { ++// userPass.put(user, pass); ++// } ++// ++// /** ++// * @see #addUser(String, String) ++// */ ++// public void addRole(String user, String role) { ++// List<String> roles = userRoles.get(user); ++// if (roles == null) { ++// roles = new ArrayList<String>(); ++// userRoles.put(user, roles); ++// } ++// roles.add(role); ++// } ++ ++ // ------- Extra customization ------- ++ // You can tune individual tomcat objects, using internal APIs ++ ++ /** ++ * Get the default http connector. You can set more ++ * parameters - the port is already initialized. ++ * ++ * Alternatively, you can construct a Connector and set any params, ++ * then call addConnector(Connector) ++ * ++ * @return A connector object that can be customized ++ */ ++ public Connector getConnector() { ++ getServer(); ++ if (connector != null) { ++ return connector; ++ } ++ ++ // The same as in standard Tomcat configuration. ++ // This creates an APR HTTP connector if AprLifecycleListener has been ++ // configured (created) and Tomcat Native library is available. ++ // Otherwise it creates a BIO HTTP connector (Http11Protocol). ++ try { ++ connector = new Connector("HTTP/1.1"); ++ } catch (RuntimeException e) { ++ throw e; ++ } catch (Exception e) { ++ // Never happens. Connector() declares that it can throw ++ // an Exception, but never throws one. ++ throw new RuntimeException(e); ++ } ++ connector.setPort(port); ++ service.addConnector( connector ); ++ return connector; ++ } ++ ++ public void setConnector(Connector connector) { ++ this.connector = connector; ++ } ++ ++ /** ++ * Get the service object. Can be used to add more ++ * connectors and few other global settings. ++ */ ++ public Service getService() { ++ getServer(); ++ return service; ++ } ++ ++ /** ++ * Sets the current host - all future webapps will ++ * be added to this host. When tomcat starts, the ++ * host will be the default host. ++ * ++ * @param host ++ */ ++ public void setHost(Host host) { ++ this.host = host; ++ } ++ ++ public Host getHost() { ++ if (host == null) { ++ host = new StandardHost(); ++ host.setName(hostname); ++ ++ getEngine().addChild( host ); ++ } ++ return host; ++ } ++ ++// /** ++// * Set a custom realm for auth. If not called, a simple ++// * default will be used, using an internal map. ++// * ++// * Must be called before adding a context. ++// * ++// * @deprecated Will be removed in Tomcat 8.0.x. ++// */ ++// @Deprecated ++// public void setDefaultRealm(Realm realm) { ++// defaultRealm = realm; ++// } ++// ++ ++ /** ++ * Access to the engine, for further customization. ++ */ ++ public Engine getEngine() { ++ if(engine == null ) { ++ getServer(); ++ engine = new StandardEngine(); ++ engine.setName( "Tomcat" ); ++ engine.setDefaultHost(hostname); ++ // @Deprecated ++ // if (defaultRealm == null) { ++ // initSimpleAuth(); ++ // } ++ // engine.setRealm(defaultRealm); ++ service.setContainer(engine); ++ } ++ return engine; ++ } ++ ++ /** ++ * Get the server object. You can add listeners and few more ++ * customizations. JNDI is disabled by default. ++ */ ++ public Server getServer() { ++ ++ if (server != null) { ++ return server; ++ } ++ ++ initBaseDir(); ++ ++ System.setProperty("catalina.useNaming", "false"); ++ ++ server = new StandardServer(); ++ server.setPort(-1); ++ ++ service = new StandardService(); ++ service.setName("Tomcat"); ++ server.addService(service); ++ return server; ++ } ++ ++ public Context addContext(Host host, String contextPath, String dir) { ++ return addContext(host, contextPath, contextPath, dir); ++ } ++ ++ private Context addContext(Host host, String contextPath, String contextName, ++ String dir) { ++// silence(host, contextPath); ++ Context ctx = createContext(host, contextPath); ++ ctx.setName(contextName); ++ ctx.setPath(contextPath); ++ ctx.setDocBase(dir); ++ ((Lifecycle) ctx).addLifecycleListener(new FixContextListener()); ++ ++ if (host == null) { ++ getHost().addChild(ctx); ++ } else { ++ host.addChild(ctx); ++ } ++ return ctx; ++ } ++ ++ public Context addWebapp(Host host, String contextPath, String docBase) { ++ return addWebapp(host, contextPath, contextPath, docBase); ++ } ++ ++ /** ++ * @see #addWebapp(String, String) ++ * ++ * @param name Ignored. The contextPath will be used ++ * ++ * @deprecated Use {@link #addWebapp(Host, String, String)} ++ */ ++ @Deprecated ++ private Context addWebapp(Host host, String contextPath, String name, String docBase) { ++// silence(host, contextPath); ++ ++ Context ctx = createContext(host, contextPath); ++ ctx.setPath(contextPath); ++ ctx.setDocBase(docBase); ++ ++ ((Lifecycle) ctx).addLifecycleListener(new DefaultWebXmlListener()); ++ ctx.setConfigFile(getWebappConfigFile(docBase, contextPath)); ++ ++ ContextConfig ctxCfg = new ContextConfig(); ++ ((Lifecycle) ctx).addLifecycleListener(ctxCfg); ++ ++// // prevent it from looking ( if it finds one - it'll have dup error ) ++// ctxCfg.setDefaultWebXml(noDefaultWebXmlPath()); ++ ++ if (host == null) { ++ getHost().addChild(ctx); ++ } else { ++ host.addChild(ctx); ++ } ++ ++ return ctx; ++ } ++ ++// /** ++// * Return a listener that provides the required configuration items for JSP ++// * processing. From the standard Tomcat global web.xml. Pass this to ++// * {@link Context#addLifecycleListener(LifecycleListener)} and then pass the ++// * result of {@link #noDefaultWebXmlPath()} to ++// * {@link ContextConfig#setDefaultWebXml(String)}. ++// * @return a listener object that configures default JSP processing. ++// */ ++// public LifecycleListener getDefaultWebXmlListener() { ++// return new DefaultWebXmlListener(); ++// } ++// ++// /** ++// * @return a pathname to pass to ++// * {@link ContextConfig#setDefaultWebXml(String)} when using ++// * {@link #getDefaultWebXmlListener()}. ++// */ ++// public String noDefaultWebXmlPath() { ++// return Constants.NoDefaultWebXml; ++// } ++// ++// /** ++// * For complex configurations, this accessor allows callers of this class ++// * to obtain the simple realm created by default. ++// * @return the simple in-memory realm created by default. ++// * @deprecated Will be removed in Tomcat 8.0.x ++// */ ++// @Deprecated ++// public Realm getDefaultRealm() { ++// if (defaultRealm == null) { ++// initSimpleAuth(); ++// } ++// return defaultRealm; ++// } ++// ++// ++// // ---------- Helper methods and classes ------------------- ++// ++// /** ++// * Create an in-memory realm. You can replace it for contexts with a real ++// * one. The Realm created here will be added to the Engine by default and ++// * may be replaced at the Engine level or over-ridden (as per normal Tomcat ++// * behaviour) at the Host or Context level. ++// * @deprecated Will be removed in Tomcat 8.0.x ++// */ ++// @Deprecated ++// protected void initSimpleAuth() { ++// defaultRealm = new RealmBase() { ++// @Override ++// protected String getName() { ++// return "Simple"; ++// } ++// ++// @Override ++// protected String getPassword(String username) { ++// return userPass.get(username); ++// } ++// ++// @Override ++// protected Principal getPrincipal(String username) { ++// Principal p = userPrincipals.get(username); ++// if (p == null) { ++// String pass = userPass.get(username); ++// if (pass != null) { ++// p = new GenericPrincipal(username, pass, ++// userRoles.get(username)); ++// userPrincipals.put(username, p); ++// } ++// } ++// return p; ++// } ++// ++// }; ++// } ++ ++ protected void initBaseDir() { ++ String catalinaHome = System.getProperty(Globals.CATALINA_HOME_PROP); ++ if (basedir == null) { ++ basedir = System.getProperty(Globals.CATALINA_BASE_PROP); ++ } ++ if (basedir == null) { ++ basedir = catalinaHome; ++ } ++ if (basedir == null) { ++ // Create a temp dir. ++ basedir = System.getProperty("user.dir") + "/tomcat." + port; ++ File home = new File(basedir); ++ home.mkdir(); ++ if (!home.isAbsolute()) { ++ try { ++ basedir = home.getCanonicalPath(); ++ } catch (IOException e) { ++ basedir = home.getAbsolutePath(); ++ } ++ } ++ } ++ if (catalinaHome == null) { ++ System.setProperty(Globals.CATALINA_HOME_PROP, basedir); ++ } ++ System.setProperty(Globals.CATALINA_BASE_PROP, basedir); ++ } ++ ++// Not needed. See BZ 58905. ++// ++// static final String[] silences = new String[] { ++// "org.apache.coyote.http11.Http11Protocol", ++// "org.apache.catalina.core.StandardService", ++// "org.apache.catalina.core.StandardEngine", ++// "org.apache.catalina.startup.ContextConfig", ++// "org.apache.catalina.core.ApplicationContext", ++// "org.apache.catalina.core.AprLifecycleListener" ++// }; ++// ++// /** ++// * Controls if the loggers will be silenced or not. ++// * @param silent <code>true</code> sets the log level to WARN for the ++// * loggers that log information on Tomcat start up. This ++// * prevents the usual startup information being logged. ++// * <code>false</code> sets the log level to the default ++// * level of INFO. ++// */ ++// public void setSilent(boolean silent) { ++// for (String s : silences) { ++// Logger logger = Logger.getLogger(s); ++// pinnedLoggers.put(s, logger); ++// if (silent) { ++// logger.setLevel(Level.WARNING); ++// } else { ++// logger.setLevel(Level.INFO); ++// } ++// } ++// } ++// ++// private void silence(Host host, String ctx) { ++// String loggerName = getLoggerName(host, ctx); ++// Logger logger = Logger.getLogger(loggerName); ++// pinnedLoggers.put(loggerName, logger); ++// logger.setLevel(Level.WARNING); ++// } ++// ++// private String getLoggerName(Host host, String ctx) { ++// String loggerName = "org.apache.catalina.core.ContainerBase.[default].["; ++// if (host == null) { ++// loggerName += getHost().getName(); ++// } else { ++// loggerName += host.getName(); ++// } ++// loggerName += "].["; ++// loggerName += ctx; ++// loggerName += "]"; ++// return loggerName; ++// } ++ ++ /** ++ * Create the configured {@link Context} for the given <code>host</code>. ++ * The default constructor of the class that was configured with ++ * {@link StandardHost#setContextClass(String)} will be used ++ * ++ * @param host ++ * host for which the {@link Context} should be created, or ++ * <code>null</code> if default host should be used ++ * @param url ++ * path of the webapp which should get the {@link Context} ++ * @return newly created {@link Context} ++ */ ++ private Context createContext(Host host, String url) { ++ String contextClass = StandardContext.class.getName(); ++ if (host == null) { ++ host = this.getHost(); ++ } ++ if (host instanceof StandardHost) { ++ contextClass = ((StandardHost) host).getContextClass(); ++ } ++ try { ++ return (Context) Class.forName(contextClass).getConstructor() ++ .newInstance(); ++ } catch (InstantiationException e) { ++ throw new IllegalArgumentException( ++ "Can't instantiate context-class " + contextClass ++ + " for host " + host + " and url " ++ + url, e); ++ } catch (IllegalAccessException e) { ++ throw new IllegalArgumentException( ++ "Can't instantiate context-class " + contextClass ++ + " for host " + host + " and url " ++ + url, e); ++ } catch (IllegalArgumentException e) { ++ throw new IllegalArgumentException( ++ "Can't instantiate context-class " + contextClass ++ + " for host " + host + " and url " ++ + url, e); ++ } catch (InvocationTargetException e) { ++ throw new IllegalArgumentException( ++ "Can't instantiate context-class " + contextClass ++ + " for host " + host + " and url " ++ + url, e); ++ } catch (NoSuchMethodException e) { ++ throw new IllegalArgumentException( ++ "Can't instantiate context-class " + contextClass ++ + " for host " + host + " and url " ++ + url, e); ++ } catch (SecurityException e) { ++ throw new IllegalArgumentException( ++ "Can't instantiate context-class " + contextClass ++ + " for host " + host + " and url " ++ + url, e); ++ } catch (ClassNotFoundException e) { ++ throw new IllegalArgumentException( ++ "Can't instantiate context-class " + contextClass ++ + " for host " + host + " and url " ++ + url, e); ++ } ++ } ++ ++ /** ++ * Enables JNDI naming which is disabled by default. Server must implement ++ * {@link Lifecycle} in order for the {@link NamingContextListener} to be ++ * used. ++ * ++ */ ++ public void enableNaming() { ++ // Make sure getServer() has been called as that is where naming is ++ // disabled ++ getServer(); ++ server.addLifecycleListener(new NamingContextListener()); ++ ++ System.setProperty("catalina.useNaming", "true"); ++ ++ String value = "org.apache.naming"; ++ String oldValue = ++ System.getProperty(javax.naming.Context.URL_PKG_PREFIXES); ++ if (oldValue != null) { ++ if (oldValue.contains(value)) { ++ value = oldValue; ++ } else { ++ value = value + ":" + oldValue; ++ } ++ } ++ System.setProperty(javax.naming.Context.URL_PKG_PREFIXES, value); ++ ++ value = System.getProperty ++ (javax.naming.Context.INITIAL_CONTEXT_FACTORY); ++ if (value == null) { ++ System.setProperty ++ (javax.naming.Context.INITIAL_CONTEXT_FACTORY, ++ "org.apache.naming.java.javaURLContextFactory"); ++ } ++ } ++ ++// /** ++// * Provide default configuration for a context. This is the programmatic ++// * equivalent of the default web.xml. ++// * ++// * TODO: in normal Tomcat, if default-web.xml is not found, use this ++// * method ++// * ++// * @param contextPath The context to set the defaults for ++// */ ++// public void initWebappDefaults(String contextPath) { ++// Container ctx = getHost().findChild(contextPath); ++// initWebappDefaults((Context) ctx); ++// } ++ ++ /** ++ * Static version of {@link #initWebappDefaults(String)} ++ * @param ctx The context to set the defaults for ++ */ ++ public static void initWebappDefaults(Context ctx) { ++ // Default servlet ++ Wrapper servlet = addServlet( ++ ctx, "default", "org.apache.catalina.servlets.DefaultServlet"); ++ servlet.setLoadOnStartup(1); ++ //servlet.setOverridable(true); ++ ++ // JSP servlet (by class name - to avoid loading all deps) ++ servlet = addServlet( ++ ctx, "jsp", "org.apache.jasper.servlet.JspServlet"); ++ servlet.addInitParameter("fork", "false"); ++ servlet.setLoadOnStartup(3); ++ //servlet.setOverridable(true); ++ ++ // Servlet mappings ++ ctx.addServletMapping("/", "default"); ++ ctx.addServletMapping("*.jsp", "jsp"); ++ ctx.addServletMapping("*.jspx", "jsp"); ++ ++ // Sessions ++ ctx.setSessionTimeout(30); ++ ++ // MIME mappings ++ for (int i = 0; i < DEFAULT_MIME_MAPPINGS.length;) { ++ ctx.addMimeMapping(DEFAULT_MIME_MAPPINGS[i++], ++ DEFAULT_MIME_MAPPINGS[i++]); ++ } ++ ++ // Welcome files ++ ctx.addWelcomeFile("index.html"); ++ ctx.addWelcomeFile("index.htm"); ++ ctx.addWelcomeFile("index.jsp"); ++ } ++ ++ ++ /** ++ * Fix startup sequence - required if you don't use web.xml. ++ * ++ * The start() method in context will set 'configured' to false - and ++ * expects a listener to set it back to true. ++ */ ++ public static class FixContextListener implements LifecycleListener { ++ ++ public void lifecycleEvent(LifecycleEvent event) { ++ try { ++ Context context = (Context) event.getLifecycle(); ++ // Using START_EVENT, Tomcat 7+ uses CONFIGURE_START_EVENT here. ++ if (event.getType().equals(Lifecycle.START_EVENT)) { ++ context.setConfigured(true); ++ } ++// Not needed. Tomcat 6 does not support @ServletSecurity annotations. ++// // LoginConfig is required to process @ServletSecurity ++// // annotations ++// if (context.getLoginConfig() == null) { ++// context.setLoginConfig( ++// new LoginConfig("NONE", null, null, null)); ++// context.getPipeline().addValve(new NonLoginAuthenticator()); ++// } ++ } catch (ClassCastException e) { ++ return; ++ } ++ } ++ ++ } ++ ++ ++ /** ++ * Fix reload - required if reloading and using programmatic configuration. ++ * When a context is reloaded, any programmatic configuration is lost. This ++ * listener sets the equivalent of conf/web.xml when the context starts. ++ */ ++ public static class DefaultWebXmlListener implements LifecycleListener { ++ public void lifecycleEvent(LifecycleEvent event) { ++ if (Lifecycle.BEFORE_START_EVENT.equals(event.getType())) { ++ initWebappDefaults((Context) event.getLifecycle()); ++ } ++ } ++ } ++ ++ ++ /** ++ * Helper class for wrapping existing servlets. This disables servlet ++ * lifecycle and normal reloading, but also reduces overhead and provide ++ * more direct control over the servlet. ++ */ ++ public static class ExistingStandardWrapper extends StandardWrapper { ++ private final Servlet existing; ++ private boolean instanceInitialized = false; ++ private static final long serialVersionUID = 1L; ++ ++ @SuppressWarnings("deprecation") ++ public ExistingStandardWrapper( Servlet existing ) { ++ this.existing = existing; ++ if (existing instanceof javax.servlet.SingleThreadModel) { ++ singleThreadModel = true; ++ instancePool = new Stack<Servlet>(); ++ } ++ } ++ @Override ++ public synchronized Servlet loadServlet() throws ServletException { ++ if (singleThreadModel) { ++ Servlet instance; ++ try { ++ instance = existing.getClass().newInstance(); ++ } catch (InstantiationException e) { ++ throw new ServletException(e); ++ } catch (IllegalAccessException e) { ++ throw new ServletException(e); ++ } ++ instance.init(facade); ++ return instance; ++ } else { ++ if (!instanceInitialized) { ++ existing.init(facade); ++ instanceInitialized = true; ++ } ++ return existing; ++ } ++ } ++ @Override ++ public long getAvailable() { ++ return 0; ++ } ++ @Override ++ public boolean isUnavailable() { ++ return false; ++ } ++ @Override ++ public Servlet getServlet() { ++ return existing; ++ } ++ @Override ++ public String getServletClass() { ++ return existing.getClass().getName(); ++ } ++ } ++ ++ /** ++ * TODO: would a properties resource be better ? Or just parsing ++ * /etc/mime.types ? ++ * This is needed because we don't use the default web.xml, where this ++ * is encoded. ++ */ ++ private static final String[] DEFAULT_MIME_MAPPINGS = { ++ "abs", "audio/x-mpeg", ++ "ai", "application/postscript", ++ "aif", "audio/x-aiff", ++ "aifc", "audio/x-aiff", ++ "aiff", "audio/x-aiff", ++ "aim", "application/x-aim", ++ "art", "image/x-jg", ++ "asf", "video/x-ms-asf", ++ "asx", "video/x-ms-asf", ++ "au", "audio/basic", ++ "avi", "video/x-msvideo", ++ "avx", "video/x-rad-screenplay", ++ "bcpio", "application/x-bcpio", ++ "bin", "application/octet-stream", ++ "bmp", "image/bmp", ++ "body", "text/html", ++ "cdf", "application/x-cdf", ++ "cer", "application/pkix-cert", ++ "class", "application/java", ++ "cpio", "application/x-cpio", ++ "csh", "application/x-csh", ++ "css", "text/css", ++ "dib", "image/bmp", ++ "doc", "application/msword", ++ "dtd", "application/xml-dtd", ++ "dv", "video/x-dv", ++ "dvi", "application/x-dvi", ++ "eps", "application/postscript", ++ "etx", "text/x-setext", ++ "exe", "application/octet-stream", ++ "gif", "image/gif", ++ "gtar", "application/x-gtar", ++ "gz", "application/x-gzip", ++ "hdf", "application/x-hdf", ++ "hqx", "application/mac-binhex40", ++ "htc", "text/x-component", ++ "htm", "text/html", ++ "html", "text/html", ++ "ief", "image/ief", ++ "jad", "text/vnd.sun.j2me.app-descriptor", ++ "jar", "application/java-archive", ++ "java", "text/x-java-source", ++ "jnlp", "application/x-java-jnlp-file", ++ "jpe", "image/jpeg", ++ "jpeg", "image/jpeg", ++ "jpg", "image/jpeg", ++ "js", "application/javascript", ++ "jsf", "text/plain", ++ "jspf", "text/plain", ++ "kar", "audio/midi", ++ "latex", "application/x-latex", ++ "m3u", "audio/x-mpegurl", ++ "mac", "image/x-macpaint", ++ "man", "text/troff", ++ "mathml", "application/mathml+xml", ++ "me", "text/troff", ++ "mid", "audio/midi", ++ "midi", "audio/midi", ++ "mif", "application/x-mif", ++ "mov", "video/quicktime", ++ "movie", "video/x-sgi-movie", ++ "mp1", "audio/mpeg", ++ "mp2", "audio/mpeg", ++ "mp3", "audio/mpeg", ++ "mp4", "video/mp4", ++ "mpa", "audio/mpeg", ++ "mpe", "video/mpeg", ++ "mpeg", "video/mpeg", ++ "mpega", "audio/x-mpeg", ++ "mpg", "video/mpeg", ++ "mpv2", "video/mpeg2", ++ "nc", "application/x-netcdf", ++ "oda", "application/oda", ++ "odb", "application/vnd.oasis.opendocument.database", ++ "odc", "application/vnd.oasis.opendocument.chart", ++ "odf", "application/vnd.oasis.opendocument.formula", ++ "odg", "application/vnd.oasis.opendocument.graphics", ++ "odi", "application/vnd.oasis.opendocument.image", ++ "odm", "application/vnd.oasis.opendocument.text-master", ++ "odp", "application/vnd.oasis.opendocument.presentation", ++ "ods", "application/vnd.oasis.opendocument.spreadsheet", ++ "odt", "application/vnd.oasis.opendocument.text", ++ "otg", "application/vnd.oasis.opendocument.graphics-template", ++ "oth", "application/vnd.oasis.opendocument.text-web", ++ "otp", "application/vnd.oasis.opendocument.presentation-template", ++ "ots", "application/vnd.oasis.opendocument.spreadsheet-template ", ++ "ott", "application/vnd.oasis.opendocument.text-template", ++ "ogx", "application/ogg", ++ "ogv", "video/ogg", ++ "oga", "audio/ogg", ++ "ogg", "audio/ogg", ++ "spx", "audio/ogg", ++ "flac", "audio/flac", ++ "anx", "application/annodex", ++ "axa", "audio/annodex", ++ "axv", "video/annodex", ++ "xspf", "application/xspf+xml", ++ "pbm", "image/x-portable-bitmap", ++ "pct", "image/pict", ++ "pdf", "application/pdf", ++ "pgm", "image/x-portable-graymap", ++ "pic", "image/pict", ++ "pict", "image/pict", ++ "pls", "audio/x-scpls", ++ "png", "image/png", ++ "pnm", "image/x-portable-anymap", ++ "pnt", "image/x-macpaint", ++ "ppm", "image/x-portable-pixmap", ++ "ppt", "application/vnd.ms-powerpoint", ++ "pps", "application/vnd.ms-powerpoint", ++ "ps", "application/postscript", ++ "psd", "image/vnd.adobe.photoshop", ++ "qt", "video/quicktime", ++ "qti", "image/x-quicktime", ++ "qtif", "image/x-quicktime", ++ "ras", "image/x-cmu-raster", ++ "rdf", "application/rdf+xml", ++ "rgb", "image/x-rgb", ++ "rm", "application/vnd.rn-realmedia", ++ "roff", "text/troff", ++ "rtf", "application/rtf", ++ "rtx", "text/richtext", ++ "sh", "application/x-sh", ++ "shar", "application/x-shar", ++ /*"shtml", "text/x-server-parsed-html",*/ ++ "sit", "application/x-stuffit", ++ "snd", "audio/basic", ++ "src", "application/x-wais-source", ++ "sv4cpio", "application/x-sv4cpio", ++ "sv4crc", "application/x-sv4crc", ++ "svg", "image/svg+xml", ++ "svgz", "image/svg+xml", ++ "swf", "application/x-shockwave-flash", ++ "t", "text/troff", ++ "tar", "application/x-tar", ++ "tcl", "application/x-tcl", ++ "tex", "application/x-tex", ++ "texi", "application/x-texinfo", ++ "texinfo", "application/x-texinfo", ++ "tif", "image/tiff", ++ "tiff", "image/tiff", ++ "tr", "text/troff", ++ "tsv", "text/tab-separated-values", ++ "txt", "text/plain", ++ "ulw", "audio/basic", ++ "ustar", "application/x-ustar", ++ "vxml", "application/voicexml+xml", ++ "xbm", "image/x-xbitmap", ++ "xht", "application/xhtml+xml", ++ "xhtml", "application/xhtml+xml", ++ "xls", "application/vnd.ms-excel", ++ "xml", "application/xml", ++ "xpm", "image/x-xpixmap", ++ "xsl", "application/xml", ++ "xslt", "application/xslt+xml", ++ "xul", "application/vnd.mozilla.xul+xml", ++ "xwd", "image/x-xwindowdump", ++ "vsd", "application/vnd.visio", ++ "wav", "audio/x-wav", ++ "wbmp", "image/vnd.wap.wbmp", ++ "wml", "text/vnd.wap.wml", ++ "wmlc", "application/vnd.wap.wmlc", ++ "wmls", "text/vnd.wap.wmlsc", ++ "wmlscriptc", "application/vnd.wap.wmlscriptc", ++ "wmv", "video/x-ms-wmv", ++ "wrl", "model/vrml", ++ "wspolicy", "application/wspolicy+xml", ++ "Z", "application/x-compress", ++ "z", "application/x-compress", ++ "zip", "application/zip" ++ }; ++ ++ protected String getWebappConfigFile(String path, @SuppressWarnings("unused") String contextPath) { ++ File docBase = new File(path); ++ if (docBase.isDirectory()) { ++ return getWebappConfigFileFromDirectory(docBase); ++ } else { ++ // Reading context.xml from a war file without copying it ++ // is not implemented in Tomcat 6. (BZ 48662, r928380) ++ // return getWebappConfigFileFromJar(docBase, contextPath); ++ return null; ++ } ++ } ++ ++ private String getWebappConfigFileFromDirectory(File docBase) { ++ String result = null; ++ File webAppContextXml = new File(docBase, Constants.ApplicationContextXml); ++ if (webAppContextXml.exists()) { ++ result = webAppContextXml.getAbsolutePath(); ++ } ++ return result; ++ } ++ ++// private URL getWebappConfigFileFromJar(File docBase, String url) { ++// URL result = null; ++// JarFile jar = null; ++// try { ++// jar = new JarFile(docBase); ++// JarEntry entry = jar.getJarEntry(Constants.ApplicationContextXml); ++// if (entry != null) { ++// result = new URL("jar:" + docBase.toURI().toString() + "!/" ++// + Constants.ApplicationContextXml); ++// } ++// } catch (IOException e) { ++// Logger.getLogger(getLoggerName(getHost(), url)).log(Level.WARNING, ++// "Unable to determine web application context.xml " + docBase, e); ++// } finally { ++// if (jar != null) { ++// try { ++// jar.close(); ++// } catch (IOException e) { ++// // ignore ++// } ++// } ++// } ++// return result; ++// } ++} + +Property changes on: test/org/apache/catalina/startup/Tomcat.java +___________________________________________________________________ +Added: svn:eol-style +## -0,0 +1 ## ++native +\ No newline at end of property +Index: test/org/apache/catalina/startup/FastNonSecureRandom.java +=================================================================== +--- test/org/apache/catalina/startup/FastNonSecureRandom.java (.../trunk) (revision 0) ++++ test/org/apache/catalina/startup/FastNonSecureRandom.java (.../branches/tomcat6-testing_20160106) (revision 1726111) +@@ -0,0 +1,60 @@ ++/* ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++package org.apache.catalina.startup; ++ ++import java.security.SecureRandom; ++import java.util.Random; ++ ++public class FastNonSecureRandom extends SecureRandom { ++ ++ private static final long serialVersionUID = 1L; ++ ++ private final Random random = new Random(); ++ ++ @Override ++ public String getAlgorithm() { ++ return "INSECURE"; ++ } ++ ++ @Override ++ public synchronized void setSeed(byte[] seed) { ++ // Not implemented ++ } ++ ++ @Override ++ public synchronized void setSeed(long seed) { ++ // The super class constructor calls this method earlier than our ++ // fields are initialized. Ignore the call. ++ if (random == null) { ++ return; ++ } ++ random.setSeed(seed); ++ } ++ ++ @Override ++ public synchronized void nextBytes(byte[] bytes) { ++ random.nextBytes(bytes); ++ } ++ ++ @Override ++ public byte[] generateSeed(int numBytes) { ++ byte[] value = new byte[numBytes]; ++ nextBytes(value); ++ return value; ++ } ++ ++} +\ No newline at end of file + +Property changes on: test/org/apache/catalina/startup/FastNonSecureRandom.java +___________________________________________________________________ +Added: svn:eol-style +## -0,0 +1 ## ++native +\ No newline at end of property +Index: test/org/apache/catalina/startup/TomcatBaseTest.java +=================================================================== +--- test/org/apache/catalina/startup/TomcatBaseTest.java (.../trunk) (revision 0) ++++ test/org/apache/catalina/startup/TomcatBaseTest.java (.../branches/tomcat6-testing_20160106) (revision 1726111) +@@ -0,0 +1,796 @@ ++/* ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++package org.apache.catalina.startup; ++ ++import java.io.BufferedInputStream; ++import java.io.File; ++import java.io.IOException; ++import java.io.InputStream; ++import java.io.OutputStream; ++import java.io.PrintWriter; ++import java.net.HttpURLConnection; ++import java.net.InetAddress; ++import java.net.URL; ++import java.util.Enumeration; ++import java.util.HashMap; ++import java.util.List; ++import java.util.Map; ++ ++import javax.servlet.ServletContext; ++import javax.servlet.ServletException; ++import javax.servlet.http.HttpServlet; ++import javax.servlet.http.HttpServletRequest; ++import javax.servlet.http.HttpServletResponse; ++import javax.servlet.http.HttpSession; ++ ++import static org.junit.Assert.assertNull; ++import static org.junit.Assert.fail; ++ ++import org.junit.After; ++import org.junit.Assert; ++import org.junit.Before; ++ ++import org.apache.catalina.Container; ++import org.apache.catalina.LifecycleException; ++import org.apache.catalina.Manager; ++import org.apache.catalina.Server; ++import org.apache.catalina.ServerFactory; ++import org.apache.catalina.Service; ++import org.apache.catalina.connector.Connector; ++import org.apache.catalina.core.AprLifecycleListener; ++import org.apache.catalina.core.StandardServer; ++import org.apache.catalina.session.ManagerBase; ++import org.apache.catalina.session.StandardManager; ++import org.apache.catalina.valves.AccessLogValve; ++import org.apache.tomcat.util.buf.ByteChunk; ++ ++/** ++ * Base test case that provides a Tomcat instance for each test - mainly so we ++ * don't have to keep writing the cleanup code. ++ */ ++public abstract class TomcatBaseTest extends LoggingBaseTest { ++ private Tomcat tomcat; ++ private boolean accessLogEnabled = false; ++ ++ public static final String TEMP_DIR = System.getProperty("java.io.tmpdir"); ++ ++ /** ++ * Make Tomcat instance accessible to sub-classes. ++ */ ++ public Tomcat getTomcatInstance() { ++ return tomcat; ++ } ++ ++ /** ++ * Sub-classes need to know port so they can connect ++ */ ++ public int getPort() { ++ return tomcat.getConnector().getLocalPort(); ++ } ++ ++ /** ++ * Sub-classes may want to check, whether an AccessLogValve is active ++ */ ++ public boolean isAccessLogEnabled() { ++ return accessLogEnabled; ++ } ++ ++ @Before ++ @Override ++ public void setUp() throws Exception { ++ super.setUp(); ++ ++ // Trigger loading of catalina.properties ++ CatalinaProperties.getProperty("foo"); ++ ++ File appBase = new File(getTemporaryDirectory(), "webapps"); ++ if (!appBase.exists() && !appBase.mkdir()) { ++ fail("Unable to create appBase for test"); ++ } ++ ++ // A sanity check that the Server reference has been cleared after ++ // the previous test run ++ assertNull("A Server has already been created.", ++ ServerFactory.getServer(false)); ++ ++ tomcat = new TomcatWithFastSessionIDs(); ++ ++ String protocol = getProtocol(); ++ Connector connector = new Connector(protocol); ++ // Listen only on localhost ++ connector.setAttribute("address", ++ InetAddress.getByName("localhost").getHostAddress()); ++ // Use random free port ++ connector.setPort(0); ++ // Mainly set to reduce timeouts during async tests ++ connector.setAttribute("connectionTimeout", "3000"); ++ tomcat.getService().addConnector(connector); ++ tomcat.setConnector(connector); ++ ++ // Add AprLifecycleListener if we are using the Apr connector ++ if (protocol.contains("Apr")) { ++ StandardServer server = (StandardServer) tomcat.getServer(); ++ AprLifecycleListener listener = new AprLifecycleListener(); ++ listener.setSSLRandomSeed("/dev/urandom"); ++ server.addLifecycleListener(listener); ++ connector.setAttribute("pollerThreadCount", Integer.valueOf(1)); ++ } ++ ++ File catalinaBase = getTemporaryDirectory(); ++ tomcat.setBaseDir(catalinaBase.getAbsolutePath()); ++ tomcat.getHost().setAppBase(appBase.getAbsolutePath()); ++ ++ accessLogEnabled = Boolean.parseBoolean( ++ System.getProperty("tomcat.test.accesslog", "false")); ++ if (accessLogEnabled) { ++ String accessLogDirectory = System ++ .getProperty("tomcat.test.reports"); ++ if (accessLogDirectory == null) { ++ accessLogDirectory = new File(getBuildDirectory(), "logs") ++ .toString(); ++ } ++ AccessLogValve alv = new AccessLogValve(); ++ alv.setDirectory(accessLogDirectory); ++ alv.setPattern("%h %l %u %t \"%r\" %s %b %I %D"); ++ tomcat.getHost().getPipeline().addValve(alv); ++ } ++ ++ // Cannot delete the whole tempDir, because logs are there, ++ // but delete known subdirectories of it. ++ addDeleteOnTearDown(new File(catalinaBase, "webapps")); ++ addDeleteOnTearDown(new File(catalinaBase, "work")); ++ } ++ ++ protected String getProtocol() { ++ // Has a protocol been specified ++ String protocol = System.getProperty("tomcat.test.protocol"); ++ ++ // Use BIO by default ++ if (protocol == null) { ++ protocol = "org.apache.coyote.http11.Http11Protocol"; ++ } ++ ++ return protocol; ++ } ++ ++ @After ++ @Override ++ public void tearDown() throws Exception { ++ try { ++ if (tomcat.server != null) { ++ tomcat.stop(); ++ tomcat.destroy(); ++ } ++ } finally { ++ ServerFactory.clear(); ++ super.tearDown(); ++ } ++ } ++ ++ /** ++ * Simple Hello World servlet for use by test cases ++ */ ++ public static final class HelloWorldServlet extends HttpServlet { ++ ++ private static final long serialVersionUID = 1L; ++ ++ public static final String RESPONSE_TEXT = ++ "<html><body><p>Hello World</p></body></html>"; ++ ++ @Override ++ protected void doGet(HttpServletRequest req, HttpServletResponse resp) ++ throws ServletException, IOException { ++ PrintWriter out = resp.getWriter(); ++ out.print(RESPONSE_TEXT); ++ } ++ } ++ ++ ++ public static final class RequestDescriptor { ++ ++ private final Map<String, String> requestInfo = ++ new HashMap<String, String>(); ++ private final Map<String, String> contextInitParameters = ++ new HashMap<String, String>(); ++ private final Map<String, String> contextAttributes = ++ new HashMap<String, String>(); ++ private final Map<String, String> headers = ++ new CaseInsensitiveKeyMap<String>(); ++ private final Map<String, String> attributes = ++ new HashMap<String, String>(); ++ private final Map<String, String> params = ++ new HashMap<String, String>(); ++ private final Map<String, String> sessionAttributes = ++ new HashMap<String, String>(); ++ ++ public Map<String, String> getRequestInfo() { ++ return requestInfo; ++ } ++ ++ public Map<String, String> getContextInitParameters() { ++ return contextInitParameters; ++ } ++ ++ public Map<String, String> getContextAttributes() { ++ return contextAttributes; ++ } ++ ++ public Map<String, String> getHeaders() { ++ return headers; ++ } ++ ++ public Map<String, String> getAttributes() { ++ return attributes; ++ } ++ ++ public Map<String, String> getParams() { ++ return params; ++ } ++ ++ public Map<String, String> getSessionAttributes() { ++ return sessionAttributes; ++ } ++ ++ public String getRequestInfo(String name) { ++ return requestInfo.get(name); ++ } ++ ++ public void putRequestInfo(String name, String value) { ++ requestInfo.put(name, value); ++ } ++ ++ public String getContextInitParameter(String name) { ++ return contextInitParameters.get(name); ++ } ++ ++ public void putContextInitParameter(String name, String value) { ++ contextInitParameters.put(name, value); ++ } ++ ++ public String getContextAttribute(String name) { ++ return contextAttributes.get(name); ++ } ++ ++ public void putContextAttribute(String name, String value) { ++ contextAttributes.put(name, value); ++ } ++ ++ public String getHeader(String name) { ++ return headers.get(name); ++ } ++ ++ public void putHeader(String name, String value) { ++ headers.put(name, value); ++ } ++ ++ public String getAttribute(String name) { ++ return attributes.get(name); ++ } ++ ++ public void putAttribute(String name, String value) { ++ attributes.put(name, value);
[... 1503 lines stripped ...] --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org