ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/test/org/apache/catalina/startup/TomcatBaseTest.java

Path
ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/test/org/apache/catalina/startup/TomcatBaseTest.java
Status
scanned
Type
file
Name
TomcatBaseTest.java
Extension
.java
Programming language
Java
Mime type
text/plain
File type
ASCII text, with CRLF line terminators
Tag

      
    
Rootfs path

      
    
Size
45880 (44.8 KB)
MD5
f0e3b82d042badd593921bbe848d9c14
SHA1
e68afb48e76788f85bbb0e11405a163c9f7c5bd7
SHA256
53f92399a987612641deb890a8379a719a8da2b2a51ca9a1f277e3a76c98929d
SHA512

      
    
SHA1_git
dc71e335f5846bcc2ab7faba6406d70107b961e4
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
TomcatBaseTest.java | 44.8 KB |

/* * 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.URI; import java.net.URL; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.IdentityHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; import jakarta.servlet.ServletContext; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.apache.catalina.Container; import org.apache.catalina.ContainerEvent; import org.apache.catalina.ContainerListener; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleListener; import org.apache.catalina.LifecycleState; import org.apache.catalina.Manager; import org.apache.catalina.Server; import org.apache.catalina.Service; import org.apache.catalina.Session; import org.apache.catalina.WebResourceRoot; import org.apache.catalina.connector.Connector; import org.apache.catalina.session.ManagerBase; import org.apache.catalina.session.StandardManager; import org.apache.catalina.util.IOTools; import org.apache.catalina.valves.AccessLogValve; import org.apache.catalina.webresources.StandardRoot; import org.apache.coyote.http11.Http11NioProtocol; import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.collections.CaseInsensitiveKeyMap; import org.apache.tomcat.util.http.Method; import org.apache.tomcat.util.res.StringManager; import org.apache.tomcat.util.scan.StandardJarScanFilter; import org.apache.tomcat.util.scan.StandardJarScanner; /** * 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 { // Used by parameterized tests. Defined here to reduce duplication. protected static final Boolean[] booleans = new Boolean[] { Boolean.FALSE, Boolean.TRUE }; protected static final int DEFAULT_CLIENT_TIMEOUT_MS = 300_000; public static final String TEMP_DIR = System.getProperty("java.io.tmpdir"); private Tomcat tomcat; private boolean accessLogEnabled = false; /** * Make the Tomcat instance available to sub-classes. * * @return A Tomcat instance without any pre-configured web applications */ public Tomcat getTomcatInstance() { return tomcat; } /** * Make the Tomcat instance preconfigured with test/webapp available to * sub-classes. * @param addJstl Should JSTL support be added to the test webapp * @param start Should the Tomcat instance be started * * @return A Tomcat instance pre-configured with the web application located * at test/webapp * * @throws LifecycleException If a problem occurs while starting the * instance */ public Tomcat getTomcatInstanceTestWebapp(boolean addJstl, boolean start) throws LifecycleException { File appDir = new File("test/webapp"); Context ctx = tomcat.addWebapp(null, "/test", appDir.getAbsolutePath()); StandardJarScanner scanner = (StandardJarScanner) ctx.getJarScanner(); StandardJarScanFilter filter = (StandardJarScanFilter) scanner.getJarScanFilter(); filter.setTldSkip(filter.getTldSkip() + ",testclasses"); filter.setPluggabilitySkip(filter.getPluggabilitySkip() + ",testclasses"); if (addJstl) { File lib = new File("webapps/examples/WEB-INF/lib"); ctx.setResources(new StandardRoot(ctx)); ctx.getResources().createWebResourceSet( WebResourceRoot.ResourceSetType.POST, "/WEB-INF/lib", lib.getAbsolutePath(), null, "/"); } if (start) { tomcat.start(); } return tomcat; } public Context getProgrammaticRootContext() { // No file system docBase required Context ctx = tomcat.addContext("", null); // Disable class path scanning - it slows the tests down by almost an order of magnitude ((StandardJarScanner) ctx.getJarScanner()).setScanClassPath(false); return ctx; } public Context getProgrammaticRootContextWithManager() { Context ctx = getProgrammaticRootContext(); if (ctx.getManager() == null) { ctx.setManager(new StandardManager()); } return ctx; } /* * 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()) { Assert.fail("Unable to create appBase for test"); } tomcat = new TomcatWithFastSessionIDs(); String protocol = getProtocol(); Connector connector = new Connector(protocol); // Listen only on localhost Assert.assertTrue(connector.setProperty("address", InetAddress.getByName("localhost").getHostAddress())); // Use random free port connector.setPort(0); // By default, a connector failure means a failed test connector.setThrowOnFailure(true); // Mainly set to reduce timeouts during async tests Assert.assertTrue(connector.setProperty("connectionTimeout", "3000")); tomcat.getService().addConnector(connector); tomcat.setConnector(connector); File catalinaBase = getTemporaryDirectory(); tomcat.setBaseDir(catalinaBase.getAbsolutePath()); tomcat.getHost().setAppBase(appBase.getAbsolutePath()); accessLogEnabled = Boolean.getBoolean("tomcat.test.accesslog"); 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 NIO by default starting with Tomcat 8 if (protocol == null) { protocol = Http11NioProtocol.class.getName(); } return protocol; } @After @Override public void tearDown() throws Exception { try { // Some tests may call tomcat.destroy(), some tests may just call // tomcat.stop(), some not call either method. Make sure that stop() // & destroy() are called as necessary. if (tomcat.server != null && tomcat.server.getState() != LifecycleState.DESTROYED) { if (tomcat.server.getState() != LifecycleState.STOPPED) { tomcat.stop(); } tomcat.destroy(); } } finally { 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<>(); private final Map<String, String> contextInitParameters = new HashMap<>(); private final Map<String, String> contextAttributes = new HashMap<>(); private final Map<String, String> headers = new CaseInsensitiveKeyMap<>(); private final Map<String, String> attributes = new HashMap<>(); private final Map<String, String> params = new HashMap<>(); private final Map<String, String> sessionAttributes = new HashMap<>(); 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); } public String getParam(String name) { return params.get(name); } public void putParam(String name, String value) { params.put(name, value); } public String getSessionAttribute(String name) { return sessionAttributes.get(name); } public void putSessionAttribute(String name, String value) { sessionAttributes.put(name, value); } public void compare (RequestDescriptor request) { Map<String, String> base; Map<String, String> cmp; base = request.getRequestInfo(); cmp = this.getRequestInfo(); for (String name: base.keySet()) { Assert.assertEquals("Request info " + name, base.get(name), cmp.get(name)); } base = request.getContextInitParameters(); cmp = this.getContextInitParameters(); for (String name: base.keySet()) { Assert.assertEquals("Context parameter " + name, base.get(name), cmp.get(name)); } base = request.getContextAttributes(); cmp = this.getContextAttributes(); for (String name: base.keySet()) { Assert.assertEquals("Context attribute " + name, base.get(name), cmp.get(name)); } base = request.getHeaders(); cmp = this.getHeaders(); for (String name: base.keySet()) { Assert.assertEquals("Header " + name, base.get(name), cmp.get(name)); } base = request.getAttributes(); cmp = this.getAttributes(); for (String name: base.keySet()) { Assert.assertEquals("Attribute " + name, base.get(name), cmp.get(name)); } base = request.getParams(); cmp = this.getParams(); for (String name: base.keySet()) { Assert.assertEquals("Param " + name, base.get(name), cmp.get(name)); } base = request.getSessionAttributes(); cmp = this.getSessionAttributes(); for (String name: base.keySet()) { Assert.assertEquals("Session attribute " + name, base.get(name), cmp.get(name)); } } } public static final class SnoopResult { public static RequestDescriptor parse(String body) { int n; int m; String key; String value; String name; RequestDescriptor request = new RequestDescriptor(); for (String line: body.split(System.lineSeparator())) { n = line.indexOf(": "); if (n > 0) { key = line.substring(0, n); value = line.substring(n + 2); m = key.indexOf(':'); if (m > 0) { name = key.substring(m + 1); key = key.substring(0, m); if (key.equals("CONTEXT-PARAM")) { request.putContextInitParameter(name, value); } else if (key.equals("CONTEXT-ATTRIBUTE")) { request.putContextAttribute(name, value); } else if (key.equals("HEADER")) { request.putHeader(name, value); } else if (key.equals("ATTRIBUTE")) { request.putAttribute(name, value); } else if (key.equals("PARAM")) { request.putParam(name, value); } else if (key.equals("SESSION-ATTRIBUTE")) { request.putSessionAttribute(name, value); } else { request.putRequestInfo(key + ":" + name, value); } } else { request.putRequestInfo(key, value); } } } return request; } } /** * Simple servlet that dumps request information. Tests using this should * note that additional information may be added to in the future and should * therefore test return values using SnoopResult. */ public static final class SnoopServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name; StringBuilder value; Object attribute; response.setContentType("text/plain"); response.setCharacterEncoding("UTF-8"); ServletContext ctx = this.getServletContext(); HttpSession session = request.getSession(false); PrintWriter out = response.getWriter(); out.println("CONTEXT-NAME: " + ctx.getServletContextName()); out.println("CONTEXT-PATH: " + ctx.getContextPath()); out.println("CONTEXT-MAJOR-VERSION: " + ctx.getMajorVersion()); out.println("CONTEXT-MINOR-VERSION: " + ctx.getMinorVersion()); out.println("CONTEXT-SERVER-INFO: " + ctx.getServerInfo()); for (Enumeration<String> e = ctx.getInitParameterNames(); e.hasMoreElements();) { name = e.nextElement(); out.println("CONTEXT-INIT-PARAM:" + name + ": " + ctx.getInitParameter(name)); } for (Enumeration<String> e = ctx.getAttributeNames(); e.hasMoreElements();) { name = e.nextElement(); out.println("CONTEXT-ATTRIBUTE:" + name + ": " + ctx.getAttribute(name)); } out.println("REQUEST-CONTEXT-PATH: " + request.getContextPath()); out.println("REQUEST-SERVER-NAME: " + request.getServerName()); out.println("REQUEST-SERVER-PORT: " + request.getServerPort()); out.println("REQUEST-LOCAL-NAME: " + request.getLocalName()); out.println("REQUEST-LOCAL-ADDR: " + request.getLocalAddr()); out.println("REQUEST-LOCAL-PORT: " + request.getLocalPort()); out.println("REQUEST-REMOTE-HOST: " + request.getRemoteHost()); out.println("REQUEST-REMOTE-ADDR: " + request.getRemoteAddr()); out.println("REQUEST-REMOTE-PORT: " + request.getRemotePort()); out.println("REQUEST-PROTOCOL: " + request.getProtocol()); out.println("REQUEST-SCHEME: " + request.getScheme()); out.println("REQUEST-IS-SECURE: " + request.isSecure()); out.println("REQUEST-URI: " + request.getRequestURI()); out.println("REQUEST-URL: " + request.getRequestURL()); out.println("REQUEST-SERVLET-PATH: " + request.getServletPath()); out.println("REQUEST-METHOD: " + request.getMethod()); out.println("REQUEST-PATH-INFO: " + request.getPathInfo()); out.println("REQUEST-PATH-TRANSLATED: " + request.getPathTranslated()); out.println("REQUEST-QUERY-STRING: " + request.getQueryString()); out.println("REQUEST-REMOTE-USER: " + request.getRemoteUser()); out.println("REQUEST-AUTH-TYPE: " + request.getAuthType()); out.println("REQUEST-USER-PRINCIPAL: " + request.getUserPrincipal()); out.println("REQUEST-CHARACTER-ENCODING: " + request.getCharacterEncoding()); out.println("REQUEST-CONTENT-LENGTH: " + request.getContentLengthLong()); out.println("REQUEST-CONTENT-TYPE: " + request.getContentType()); out.println("REQUEST-LOCALE: " + request.getLocale()); for (Enumeration<String> e = request.getHeaderNames(); e.hasMoreElements();) { name = e.nextElement(); value = new StringBuilder(); for (Enumeration<String> h = request.getHeaders(name); h.hasMoreElements();) { value.append(h.nextElement()); if (h.hasMoreElements()) { value.append(';'); } } out.println("HEADER:" + name + ": " + value); } for (Enumeration<String> e = request.getAttributeNames(); e.hasMoreElements();) { name = e.nextElement(); attribute = request.getAttribute(name); out.println("ATTRIBUTE:" + name + ": " + (attribute != null ? attribute : "(null)")); } for (Enumeration<String> e = request.getParameterNames(); e.hasMoreElements();) { name = e.nextElement(); value = new StringBuilder(); String values[] = request.getParameterValues(name); int m = values.length; for (int j = 0; j < m; j++) { value.append(values[j]); if (j < m - 1) { value.append(';'); } } out.println("PARAM:" + name + ": " + value); } out.println("SESSION-REQUESTED-ID: " + request.getRequestedSessionId()); out.println("SESSION-REQUESTED-ID-COOKIE: " + request.isRequestedSessionIdFromCookie()); out.println("SESSION-REQUESTED-ID-URL: " + request.isRequestedSessionIdFromURL()); out.println("SESSION-REQUESTED-ID-VALID: " + request.isRequestedSessionIdValid()); if (session != null) { out.println("SESSION-ID: " + session.getId()); out.println("SESSION-CREATION-TIME: " + session.getCreationTime()); out.println("SESSION-LAST-ACCESSED-TIME: " + session.getLastAccessedTime()); out.println("SESSION-MAX-INACTIVE-INTERVAL: " + session.getMaxInactiveInterval()); out.println("SESSION-IS-NEW: " + session.isNew()); for (Enumeration<String> e = session.getAttributeNames(); e.hasMoreElements();) { name = e.nextElement(); attribute = session.getAttribute(name); out.println("SESSION-ATTRIBUTE:" + name + ": " + (attribute != null ? attribute : "(null)")); } } int bodySize = 0; if (Method.PUT.equals(request.getMethod())) { InputStream is = request.getInputStream(); int read = 0; byte[] buffer = new byte[8192]; while (read != -1) { read = is.read(buffer); if (read > -1) { bodySize += read; } } } out.println("REQUEST-BODY-SIZE: " + bodySize); } } /** * Servlet that simply echos the request body back as the response body. */ public static class EchoBodyServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // NO-OP - No body to echo } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Beware of clients that try to send the whole request body before // reading any of the response. They may cause this test to lock up. try (InputStream is = req.getInputStream(); OutputStream os = resp.getOutputStream()) { IOTools.flow(is, os); } } } /* * Wrapper for getting the response. */ public static ByteChunk getUrl(String path) throws IOException { ByteChunk out = new ByteChunk(); getUrl(path, out, null); return out; } public static int getUrl(String path, ByteChunk out, Map<String, List<String>> resHead) throws IOException { return getUrl(path, out, null, resHead); } public static int getUrl(String path, ByteChunk out, boolean followRedirects) throws IOException { return methodUrl(path, out, DEFAULT_CLIENT_TIMEOUT_MS, null, null, Method.GET, followRedirects); } public static int headUrl(String path, ByteChunk out, Map<String, List<String>> resHead) throws IOException { return methodUrl(path, out, DEFAULT_CLIENT_TIMEOUT_MS, null, resHead, Method.HEAD); } public static int getUrl(String path, ByteChunk out, Map<String, List<String>> reqHead, Map<String, List<String>> resHead) throws IOException { return getUrl(path, out, DEFAULT_CLIENT_TIMEOUT_MS, reqHead, resHead); } public static int getUrl(String path, ByteChunk out, int readTimeout, Map<String, List<String>> reqHead, Map<String, List<String>> resHead) throws IOException { return methodUrl(path, out, readTimeout, reqHead, resHead, Method.GET); } public static int methodUrl(String path, ByteChunk out, int readTimeout, Map<String, List<String>> reqHead, Map<String, List<String>> resHead, String method) throws IOException { return methodUrl(path, out, readTimeout, reqHead, resHead, method, true); } public static int methodUrl(String path, ByteChunk out, int readTimeout, Map<String, List<String>> reqHead, Map<String, List<String>> resHead, String method, boolean followRedirects) throws IOException { URL url = URI.create(path).toURL(); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setUseCaches(false); connection.setReadTimeout(readTimeout); connection.setRequestMethod(method); connection.setInstanceFollowRedirects(followRedirects); if (reqHead != null) { for (Map.Entry<String, List<String>> entry : reqHead.entrySet()) { StringBuilder valueList = new StringBuilder(); for (String value : entry.getValue()) { if (valueList.length() > 0) { valueList.append(','); } valueList.append(value); } connection.setRequestProperty(entry.getKey(), valueList.toString()); } } connection.connect(); int rc = connection.getResponseCode(); if (resHead != null) { // Skip the entry with null key that is used for the response line // that some Map implementations may not accept. for (Map.Entry<String, List<String>> entry : connection.getHeaderFields().entrySet()) { if (entry.getKey() != null) { resHead.put(entry.getKey(), entry.getValue()); } } } InputStream is; if (rc < 400) { is = connection.getInputStream(); } else { is = connection.getErrorStream(); } if (is != null) { try (BufferedInputStream bis = new BufferedInputStream(is)) { byte[] buf = new byte[2048]; int rd = 0; while((rd = bis.read(buf)) > 0) { out.append(buf, 0, rd); } } } return rc; } public static ByteChunk postUrl(byte[] body, String path) throws IOException { ByteChunk out = new ByteChunk(); postUrl(body, path, out, null); return out; } public static int postUrl(byte[] body, String path, ByteChunk out, Map<String, List<String>> resHead) throws IOException { return postUrl(body, path, out, null, resHead); } public static int postUrl(final byte[] body, String path, ByteChunk out, Map<String, List<String>> reqHead, Map<String, List<String>> resHead) throws IOException { BytesStreamer s = new BytesStreamer() { boolean done = false; @Override public byte[] next() { done = true; return body; } @Override public int getLength() { return body!=null?body.length:0; } @Override public int available() { if (done) { return 0; } else { return getLength(); } } }; return postUrl(false,s,path,out,reqHead,resHead); } public static int postUrl(boolean stream, BytesStreamer streamer, String path, ByteChunk out, Map<String, List<String>> reqHead, Map<String, List<String>> resHead) throws IOException { URL url = URI.create(path).toURL(); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setReadTimeout(1000000); if (reqHead != null) { for (Map.Entry<String, List<String>> entry : reqHead.entrySet()) { StringBuilder valueList = new StringBuilder(); for (String value : entry.getValue()) { if (valueList.length() > 0) { valueList.append(','); } valueList.append(value); } connection.setRequestProperty(entry.getKey(), valueList.toString()); } } if (streamer != null && stream) { if (streamer.getLength()>0) { connection.setFixedLengthStreamingMode(streamer.getLength()); } else { connection.setChunkedStreamingMode(1024); } } connection.connect(); // Write the request body try (OutputStream os = connection.getOutputStream()) { while (streamer != null && streamer.available() > 0) { byte[] next = streamer.next(); os.write(next); os.flush(); } } int rc = connection.getResponseCode(); if (resHead != null) { Map<String, List<String>> head = connection.getHeaderFields(); resHead.putAll(head); } InputStream is; if (rc < 400) { is = connection.getInputStream(); } else { is = connection.getErrorStream(); } try (BufferedInputStream bis = new BufferedInputStream(is)) { byte[] buf = new byte[2048]; int rd = 0; while((rd = bis.read(buf)) > 0) { out.append(buf, 0, rd); } } return rc; } protected static String getStatusCode(String statusLine) { if (statusLine == null || statusLine.length() < 12) { return statusLine; } else { return statusLine.substring(9, 12); } } protected static String getSingleHeader(String header, Map<String,List<String>> headers) { // Assume headers is never null // Assume that either: // a) is correct since HTTP headers are case insensitive but most Map // implementations are case-sensitive; or // b) CaseInsensitiveKeyMap or similar is used List<String> headerValues = headers.get(header); // Looking for a single header. No matches are OK if (headerValues == null) { return null; } // Found a single header - return the header value if (headerValues.size() == 1) { return headerValues.get(0); } // More than one header value is an error throw new IllegalStateException("Found multiple headers for [" + header + "]"); } private static class TomcatWithFastSessionIDs extends Tomcat { @Override public void start() throws LifecycleException { // Use fast, insecure session ID generation for all tests Server server = getServer(); for (Service service : server.findServices()) { Container e = service.getContainer(); for (Container h : e.findChildren()) { for (Container c : h.findChildren()) { Manager m = ((Context) c).getManager(); if (m == null) { m = new StandardManager(); ((Context) c).setManager(m); } if (m instanceof ManagerBase) { ((ManagerBase) m).setSecureRandomClass( "org.apache.catalina.startup.FastNonSecureRandom"); } } } } super.start(); } } public static void recursiveCopy(final Path src, final Path dest) throws IOException { Files.walkFileTree(src, new FileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { Files.copy(dir, dest.resolve(src.relativize(dir))); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Path destPath = dest.resolve(src.relativize(file)); Files.copy(file, destPath); // Make sure that HostConfig thinks all newly copied files have // been modified. Assert.assertTrue("Failed to set last modified for [" + destPath + "]", destPath.toFile().setLastModified( System.currentTimeMillis() - 2 * HostConfig.FILE_MODIFICATION_RESOLUTION_MS)); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException ioe) throws IOException { throw ioe; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException ioe) throws IOException { // NO-OP return FileVisitResult.CONTINUE; }}); } public static void skipTldsForResourceJars(Context context) { StandardJarScanner scanner = (StandardJarScanner) context.getJarScanner(); StandardJarScanFilter filter = (StandardJarScanFilter) scanner.getJarScanFilter(); filter.setTldSkip(filter.getTldSkip() + ",resources*.jar"); } public static void forceSessionMaxInactiveInterval(Context context, int newIntervalSecs) { Session[] sessions = context.getManager().findSessions(); for (Session session : sessions) { session.setMaxInactiveInterval(newIntervalSecs); } } /** * Captures logs for the given logger names in the current ClassLoader. */ public static class LogCapture implements AutoCloseable { protected final Level level; protected final String[] loggerNames; protected final List<LogRecord> logRecords = Collections.synchronizedList(new ArrayList<>()); protected final Map<Logger, Level> previousLevelsOfLoggersMap = new IdentityHashMap<>(); private volatile boolean installed = false; protected final Handler handler = new Handler() { @Override public void publish(LogRecord record) { logRecords.add(record); } @Override public void flush() { } @Override public void close() throws SecurityException { logRecords.clear(); } }; public LogCapture(Level level, String... loggerNames) { this.level = level; this.loggerNames = loggerNames; } public void attach() { if (!installed) { for (String name : loggerNames) { Logger logger = Logger.getLogger(name); logger.addHandler(handler); if (level != null) { previousLevelsOfLoggersMap.put(logger, logger.getLevel()); logger.setLevel(level); } } installed = true; } } public boolean containsText(CharSequence s) { for (LogRecord record : logRecords) { if (record.getMessage().contains(s)) { return true; } } return false; } public boolean hasException(Class<? extends Throwable> type) { for (LogRecord record : logRecords) { Throwable t = record.getThrown(); while (t != null) { if (type.isInstance(t)) {return true;} t = t.getCause(); } } return false; } @Override public void close() throws Exception { for (Logger l : previousLevelsOfLoggersMap.keySet()) { try { l.removeHandler(handler); } catch (Throwable ignore) { } try { l.setLevel(previousLevelsOfLoggersMap.get(l)); } catch (Throwable ignore) { } } previousLevelsOfLoggersMap.clear(); } } public static LogCapture attachLogCapture(Level level, String... loggerNames) { LogCapture logCapture = new LogCapture(level, loggerNames); logCapture.attach(); return logCapture; } /** * Captures webapp-scoped logs (e.g. ContextConfig/Digester) during the * CONFIGURE_START phase of a {@link Context}. */ public static class WebappLogCapture extends LogCapture implements LifecycleListener { private String lifecycleEvent = Lifecycle.CONFIGURE_START_EVENT; public WebappLogCapture(String lifecycleEvent, Level level, String... loggerNames) { this(level, loggerNames); this.lifecycleEvent = lifecycleEvent; } public WebappLogCapture(Level level, String... loggerNames) { super(level, loggerNames); } @Override public void lifecycleEvent(LifecycleEvent event) { if (this.lifecycleEvent.equals(event.getType())) { this.attach(); } } } /** * Installs a {@link WebappLogCapture} on the given {@link Context} so it runs * before {@link ContextConfig} during CONFIGURE_START. * @param ctx the webapp context * @param level level for loggers (e.g. {@code Level.ALL}) * @param loggerNames fully-qualified logger names * @return the active capture */ public static WebappLogCapture attachWebappLogCapture(Context ctx, Level level, String... loggerNames) { List<LifecycleListener> lifecycleListenersToReAdd = new ArrayList<>(); for (LifecycleListener l : ctx.findLifecycleListeners()) { if (l instanceof ContextConfig) { lifecycleListenersToReAdd.add(l); } } for (LifecycleListener l : lifecycleListenersToReAdd) { ctx.removeLifecycleListener(l); } WebappLogCapture webappLogCapture = new WebappLogCapture(level, loggerNames); ctx.addLifecycleListener(webappLogCapture); for (LifecycleListener l : lifecycleListenersToReAdd) { ctx.addLifecycleListener(l); } return webappLogCapture; } /** * Returns the localized key in a LocalStrings.properties file. * * @param packagePath The package that contains LocalStrings.properties, e.g. 'org.apache.catalina.startup' * @param key The key to find, e.g. 'versionLoggerListener.serverInfo.server.built' * @param locale The locale to use, e.g. Locale.ENGLISH * @return The prefix before the first argument placeholder and if no placeholder, returns the whole formatted string. */ public static String getKeyFromPropertiesFile(String packagePath, String key, Locale locale) { StringManager sm; if (locale != null) { sm = StringManager.getManager(packagePath, locale); } else { sm = StringManager.getManager(packagePath); } String formatted = sm.getString(key, "XXX"); int insertIndex = formatted.indexOf("XXX"); return (insertIndex == -1) ? formatted : formatted.substring(0, insertIndex); } public static String getKeyFromPropertiesFile(String packagePath, String key) { return getKeyFromPropertiesFile(packagePath, key, Locale.getDefault()); } public static String getKeyFromPropertiesFile(StringManager sm, String key) { String formatted = sm.getString(key, "XXX"); int insertIndex = formatted.indexOf("XXX"); return (insertIndex == -1) ? formatted : formatted.substring(0, insertIndex); } /** * Injects a {@link LifecycleListener} to a {@link Context} of a {@link Container} that sends {@code ADD_CHILD_EVENT}. * Useful when deploying with the Manager / HostConfig. */ public static class ContainerInjector implements ContainerListener, AutoCloseable { private final Container container; private final Predicate<Context> filter; private final Consumer<Context> action; private volatile boolean installed = false; private String containerEvent = Container.ADD_CHILD_EVENT; private ContainerInjector(Container container, Predicate<Context> filter, Consumer<Context> action, String containerEvent) { this.container = container; this.filter = filter; this.action = action; if (containerEvent != null) { this.containerEvent = containerEvent; } container.addContainerListener(this); } public static ContainerInjector inject(Container container, Predicate<Context> filter, Consumer<Context> action) { return new ContainerInjector(container, filter, action, null); } public static ContainerInjector inject(Container container, Predicate<Context> filter, Consumer<Context> action, String containerEvent) { return new ContainerInjector(container, filter, action, containerEvent); } @Override public void containerEvent(ContainerEvent event) { if (this.containerEvent.equals(event.getType()) && !installed) { Object data = event.getData(); if (data instanceof Context ctx) { if (filter != null && filter.test(ctx)) { action.accept(ctx); installed = true; } } } } @Override public void close() { container.removeContainerListener(this); } } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
3.03
Copyrights

      
    
Holders

      
    
Authors

      
    
License detections License expression License expression SPDX
apache_2_0-4bde3f57-78aa-4201-96bf-531cba09e7de apache-2.0 Apache-2.0
URL Start line End line
http://www.apache.org/licenses/LICENSE-2.0 9 9