This commit is contained in:
2024-11-30 19:03:49 +08:00
commit 1e6763c160
3806 changed files with 737676 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
/*
* 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;
/**
*
* Used by {@link TomcatBaseTest}
*
*
*/
public interface BytesStreamer {
/**
* Get the length of the content about to be streamed.
*
* @return the length if known, else -1 and chucked encoding should be used
*/
int getLength();
/**
* @return the number of bytes available in next chunk
*/
int available();
/**
* @return returns the next byte to write if {@link #available()} returns
* > 0
*/
byte[] next();
}

View File

@@ -0,0 +1,56 @@
/*
* 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.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
* Test Mock with wrong Annotation!
*
* @author Peter Rossbach
*
*/
@WebFilter(value = "/param", filterName="paramDFilter",
urlPatterns = { "/param1" , "/param2" })
public class DuplicateMappingParamFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// NO-OP
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws ServletException, IOException {
chain.doFilter(req, res);
}
@Override
public void destroy() {
// destroy
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Test Mock with wrong Annotation!
*
* @author Peter Rossbach
*/
@WebServlet(value = "/annotation/overwrite", urlPatterns ="/param2", name = "param", initParams = {
@WebInitParam(name = "foo", value = "Hello"),
@WebInitParam(name = "bar", value = "World!") })
public class DuplicateMappingParamServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
PrintWriter out = res.getWriter();
out.print("<p>" + getInitParameter("foo") + " "
+ getInitParameter("bar") + "</p>");
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,156 @@
/*
* 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.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.LogManager;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.apache.juli.ClassLoaderLogManager;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
/**
* Base class that provides logging support for test cases that respects the
* standard conf/logging.properties configuration file.
*
* <p>
* It also provides support for cleaning up temporary files after shutdown. See
* {@link #addDeleteOnTearDown(File)}.
*
* <p>
* <em>Note</em> that the logging configuration uses
* <code>${catalina.base}</code> value and thus we take care about that property
* even if the tests do not use Tomcat.
*/
public abstract class LoggingBaseTest {
private static List<File> deleteOnClassTearDown = new ArrayList<>();
protected Log log;
private static File tempDir;
private List<File> deleteOnTearDown = new ArrayList<>();
/**
* Provides name of the currently executing test method.
*/
@Rule
public final TestName testName = new TestName();
/*
* Helper method that returns the directory where Tomcat build resides. It
* is used to access resources that are part of default Tomcat deployment.
* E.g. the examples webapp.
*/
public static File getBuildDirectory() {
return new File(System.getProperty("tomcat.test.tomcatbuild",
"output/build"));
}
/*
* Helper method that returns the path of the temporary directory used by
* the test runs. The directory is configured during {@link #setUp()}.
*
* <p>
* It is used as <code>${catalina.base}</code> for the instance of Tomcat
* that is being started, but can be used to store other temporary files as
* well. Its <code>work</code> and <code>webapps</code> subdirectories are
* deleted at {@link #tearDown()}. If you have other files or directories
* that have to be deleted on cleanup, register them with
* {@link #addDeleteOnTearDown(File)}.
*/
public File getTemporaryDirectory() {
return tempDir;
}
/**
* Schedule the given file or directory to be deleted during after-test
* cleanup.
*
* @param file
* File or directory
*/
public void addDeleteOnTearDown(File file) {
deleteOnTearDown.add(file);
}
@BeforeClass
public static void setUpPerTestClass() throws Exception {
// Create catalina.base directory
File tempBase = new File(System.getProperty("tomcat.test.temp", "output/tmp"));
if (!tempBase.mkdirs() && !tempBase.isDirectory()) {
Assert.fail("Unable to create base temporary directory for tests");
}
Path tempBasePath = FileSystems.getDefault().getPath(tempBase.getAbsolutePath());
tempDir = Files.createTempDirectory(tempBasePath, "test").toFile();
System.setProperty("catalina.base", tempDir.getAbsolutePath());
// Configure logging
System.setProperty("java.util.logging.manager",
"org.apache.juli.ClassLoaderLogManager");
System.setProperty("java.util.logging.config.file",
new File(System.getProperty("tomcat.test.basedir"),
"conf/logging.properties").toString());
}
@Before
public void setUp() throws Exception {
log = LogFactory.getLog(getClass());
log.info("Starting test case [" + testName.getMethodName() + "]");
}
@After
public void tearDown() throws Exception {
for (File file : deleteOnTearDown) {
ExpandWar.delete(file);
}
deleteOnTearDown.clear();
// tempDir contains log files which will be open until JULI shuts down
deleteOnClassTearDown.add(tempDir);
}
@AfterClass
public static void tearDownPerTestClass() throws Exception {
LogManager logManager = LogManager.getLogManager();
if (logManager instanceof ClassLoaderLogManager) {
((ClassLoaderLogManager) logManager).shutdown();
} else {
logManager.reset();
}
for (File file : deleteOnClassTearDown) {
ExpandWar.delete(file);
}
deleteOnClassTearDown.clear();
}
}

View File

@@ -0,0 +1,47 @@
/*
* 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.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Peter Rossbach
*/
@WebServlet(name = "param1", initParams = {
@WebInitParam(name = "foo", value = "Hello"),
@WebInitParam(name = "bar", value = "World!") })
public class NoMappingParamServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
PrintWriter out = res.getWriter();
out.print("<p>" + getInitParameter("foo") + " "
+ getInitParameter("bar") + "</p>");
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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.IOException;
import java.io.PrintWriter;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
/**
* Test Mock to check Filter Annotations
* @author Peter Rossbach
*/
@WebFilter(value = "/param", filterName = "paramFilter", dispatcherTypes = {
DispatcherType.ERROR, DispatcherType.ASYNC }, initParams = { @WebInitParam(name = "message", value = "Servlet says: ") })
public class ParamFilter implements Filter {
private FilterConfig _filterConfig;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
_filterConfig = filterConfig;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws ServletException, IOException {
PrintWriter out = res.getWriter();
out.print(_filterConfig.getInitParameter("message"));
chain.doFilter(req, res);
}
@Override
public void destroy() {
// destroy
}
}

View File

@@ -0,0 +1,47 @@
/*
* 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.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Peter Rossbach
*/
@WebServlet(value = "/annotation/overwrite", name = "param", initParams = {
@WebInitParam(name = "foo", value = "Hello"),
@WebInitParam(name = "bar", value = "World!") }, displayName = "param", description = "param", largeIcon = "paramLarge.png", smallIcon = "paramSmall.png", loadOnStartup = 0, asyncSupported = false)
public class ParamServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
PrintWriter out = res.getWriter();
out.print("<p>" + getInitParameter("foo") + " "
+ getInitParameter("bar") + "</p>");
}
}

View File

@@ -0,0 +1,493 @@
/*
* 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.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.junit.Assert;
/**
* Simple client for unit testing. It isn't robust, it isn't secure and
* should not be used as the basis for production code. Its only purpose
* is to do the bare minimum for the unit tests.
*/
public abstract class SimpleHttpClient {
public static final String TEMP_DIR =
System.getProperty("java.io.tmpdir");
public static final String CR = "\r";
public static final String LF = "\n";
public static final String CRLF = CR + LF;
public static final String INFO_100 = "HTTP/1.1 100 ";
public static final String OK_200 = "HTTP/1.1 200 ";
public static final String CREATED_201 = "HTTP/1.1 201 ";
public static final String NOCONTENT_204 = "HTTP/1.1 204 ";
public static final String REDIRECT_302 = "HTTP/1.1 302 ";
public static final String REDIRECT_303 = "HTTP/1.1 303 ";
public static final String FAIL_400 = "HTTP/1.1 400 ";
public static final String FORBIDDEN_403 = "HTTP/1.1 403 ";
public static final String FAIL_404 = "HTTP/1.1 404 ";
public static final String FAIL_405 = "HTTP/1.1 405 ";
public static final String TIMEOUT_408 = "HTTP/1.1 408 ";
public static final String FAIL_413 = "HTTP/1.1 413 ";
public static final String FAIL_417 = "HTTP/1.1 417 ";
public static final String FAIL_50X = "HTTP/1.1 50";
public static final String FAIL_500 = "HTTP/1.1 500 ";
public static final String FAIL_501 = "HTTP/1.1 501 ";
private static final String CONTENT_LENGTH_HEADER_PREFIX =
"Content-Length: ";
protected static final String SESSION_COOKIE_NAME = "JSESSIONID";
protected static final String SESSION_PARAMETER_NAME =
SESSION_COOKIE_NAME.toLowerCase(Locale.ENGLISH);
private static final String COOKIE_HEADER_PREFIX = "Set-Cookie: ";
private static final String SESSION_COOKIE_HEADER_PREFIX =
COOKIE_HEADER_PREFIX + SESSION_COOKIE_NAME + "=";
private static final String REDIRECT_HEADER_PREFIX = "Location: ";
protected static final String SESSION_PATH_PARAMETER_PREFIX =
SESSION_PARAMETER_NAME + "=";
protected static final String SESSION_PATH_PARAMETER_TAILS = CRLF + ";?";
private static final String ELEMENT_HEAD = "<";
private static final String ELEMENT_TAIL = ">";
private static final String RESOURCE_TAG = "a";
private static final String LOGIN_TAG = "form";
private Socket socket;
private Writer writer;
private BufferedReader reader;
private int port = 8080;
private String[] request;
private boolean useContinue = false;
private boolean useCookies = true;
private int requestPause = 1000;
private String responseLine;
private List<String> responseHeaders = new ArrayList<>();
private String sessionId;
private boolean useContentLength;
private int contentLength;
private String redirectUri;
private String responseBody;
private List<String> bodyUriElements = null;
public void setPort(int thePort) {
port = thePort;
}
public void setRequest(String[] theRequest) {
request = theRequest;
}
/*
* Expect the server to reply with 100 Continue interim response
*/
public void setUseContinue(boolean theUseContinueFlag) {
useContinue = theUseContinueFlag;
}
public boolean getUseContinue() {
return useContinue;
}
public void setUseCookies(boolean theUseCookiesFlag) {
useCookies = theUseCookiesFlag;
}
public boolean getUseCookies() {
return useCookies;
}
public void setRequestPause(int theRequestPause) {
requestPause = theRequestPause;
}
public String getResponseLine() {
return responseLine;
}
public List<String> getResponseHeaders() {
return responseHeaders;
}
public String getResponseBody() {
return responseBody;
}
/**
* Return opening tags of HTML elements that were extracted by the
* {@link #extractUriElements()} method.
*
* <p>
* Note, that {@link #extractUriElements()} method has to be called
* explicitly.
*
* @return List of HTML tags, accumulated by {@link #extractUriElements()}
* method, or {@code null} if the method has not been called yet.
*/
public List<String> getResponseBodyUriElements() {
return bodyUriElements;
}
public void setUseContentLength(boolean b) {
useContentLength = b;
}
public void setSessionId(String theSessionId) {
sessionId = theSessionId;
}
public String getSessionId() {
return sessionId;
}
public String getRedirectUri() {
return redirectUri;
}
public void connect(int connectTimeout, int soTimeout)
throws UnknownHostException, IOException {
final String encoding = "ISO-8859-1";
SocketAddress addr = new InetSocketAddress("localhost", port);
socket = new Socket();
socket.setSoTimeout(soTimeout);
socket.connect(addr,connectTimeout);
OutputStream os = createOutputStream(socket);
writer = new OutputStreamWriter(os, encoding);
InputStream is = socket.getInputStream();
Reader r = new InputStreamReader(is, encoding);
reader = new BufferedReader(r);
}
public void connect() throws UnknownHostException, IOException {
connect(0,0);
}
protected OutputStream createOutputStream(Socket socket) throws IOException {
return socket.getOutputStream();
}
public void processRequest() throws IOException, InterruptedException {
processRequest(true);
}
public void processRequest(boolean wantBody)
throws IOException, InterruptedException {
sendRequest();
readResponse(wantBody);
}
/*
* Send the component parts of the request
* (be tolerant and simply skip null entries)
*/
public void sendRequest() throws InterruptedException, IOException {
boolean first = true;
for (String requestPart : request) {
if (requestPart != null) {
if (first) {
first = false;
}
else {
Thread.sleep(requestPause);
}
writer.write(requestPart);
writer.flush();
}
}
}
public void readResponse(boolean wantBody) throws IOException {
// clear any residual data before starting on this response
responseHeaders.clear();
responseBody = null;
if (bodyUriElements != null) {
bodyUriElements.clear();
}
// Read the response status line
responseLine = readLine();
// Is a 100 continue response expected?
if (useContinue) {
if (isResponse100()) {
// Skip the blank after the 100 Continue response
readLine();
// Now get the final response
responseLine = readLine();
} else {
throw new IOException("No 100 Continue response");
}
}
// Put the headers into a map, and process interesting ones
processHeaders();
// Read the body, if requested and if one exists
processBody(wantBody);
if (isResponse408()) {
// the session has timed out
sessionId = null;
}
}
/*
* Accumulate the response headers into a map, and extract
* interesting details at the same time
*/
private void processHeaders() throws IOException {
// Reset response fields
redirectUri = null;
contentLength = -1;
String line = readLine();
while ((line != null) && (line.length() > 0)) {
responseHeaders.add(line);
if (line.startsWith(CONTENT_LENGTH_HEADER_PREFIX)) {
contentLength = Integer.parseInt(line.substring(16));
}
else if (line.startsWith(COOKIE_HEADER_PREFIX)) {
if (useCookies) {
String temp = line.substring(
SESSION_COOKIE_HEADER_PREFIX.length());
temp = temp.substring(0, temp.indexOf(';'));
setSessionId(temp);
}
}
else if (line.startsWith(REDIRECT_HEADER_PREFIX)) {
redirectUri = line.substring(REDIRECT_HEADER_PREFIX.length());
}
line = readLine();
}
}
/*
* Read the body of the server response. Save its contents and
* search it for uri-elements only if requested
*/
private void processBody(boolean wantBody) throws IOException {
// Read the body, if one exists
StringBuilder builder = new StringBuilder();
if (wantBody) {
if (useContentLength && (contentLength > -1)) {
char[] body = new char[contentLength];
int read = reader.read(body);
Assert.assertEquals(contentLength, read);
builder.append(body);
}
else {
// not using content length, so just read it line by line
String line = null;
try {
while ((line = readLine()) != null) {
builder.append(line);
}
} catch (SocketException e) {
// Ignore
// May see a SocketException if the request hasn't been
// fully read when the connection is closed as that may
// trigger a TCP reset.
}
}
}
responseBody = builder.toString();
}
/**
* Scan the response body for opening tags of certain HTML elements
* (&lt;a&gt;, &lt;form&gt;). If any are found, then accumulate them.
*
* <p>
* Note: This method has the following limitations: a) It assumes that the
* response is HTML. b) It searches for lowercase tags only.
*
* @see #getResponseBodyUriElements()
*/
public void extractUriElements() {
bodyUriElements = new ArrayList<>();
if (responseBody.length() > 0) {
int ix = 0;
while ((ix = extractUriElement(responseBody, ix, RESOURCE_TAG)) > 0){
// loop
}
ix = 0;
while ((ix = extractUriElement(responseBody, ix, LOGIN_TAG)) > 0){
// loop
}
}
}
/*
* Scan an html body for a given html uri element, starting from the
* given index into the source string. If any are found, simply
* accumulate them as literal strings, including angle brackets.
* note: nested elements will not be collected.
*
* @param body HTTP body of the response
* @param startIx offset into the body to resume the scan (for iteration)
* @param elementName to scan for (only one at a time)
* @returns the index into the body to continue the scan (for iteration)
*/
private int extractUriElement(String body, int startIx, String elementName) {
String detector = ELEMENT_HEAD + elementName + " ";
int iStart = body.indexOf(detector, startIx);
if (iStart > -1) {
int iEnd = body.indexOf(ELEMENT_TAIL, iStart);
if (iEnd < 0) {
throw new IllegalArgumentException(
"Response body check failure.\n"
+ "element [" + detector + "] is not terminated with ["
+ ELEMENT_TAIL + "]\nActual: [" + body + "]");
}
String element = body.substring(iStart, iEnd);
bodyUriElements.add(element);
iStart += element.length();
}
return iStart;
}
public String readLine() throws IOException {
return reader.readLine();
}
public void disconnect() throws IOException {
writer.close();
reader.close();
socket.close();
}
public void reset() {
socket = null;
writer = null;
reader = null;
request = null;
requestPause = 1000;
useContinue = false;
resetResponse();
}
public void resetResponse() {
responseLine = null;
responseHeaders = new ArrayList<>();
responseBody = null;
}
public boolean responseLineStartsWith(String expected) {
String line = getResponseLine();
if (line == null) {
return false;
}
return line.startsWith(expected);
}
public boolean isResponse100() {
return responseLineStartsWith(INFO_100);
}
public boolean isResponse200() {
return responseLineStartsWith(OK_200);
}
public boolean isResponse201() {
return responseLineStartsWith(CREATED_201);
}
public boolean isResponse204() {
return responseLineStartsWith(NOCONTENT_204);
}
public boolean isResponse302() {
return responseLineStartsWith(REDIRECT_302);
}
public boolean isResponse303() {
return responseLineStartsWith(REDIRECT_303);
}
public boolean isResponse400() {
return responseLineStartsWith(FAIL_400);
}
public boolean isResponse403() {
return responseLineStartsWith(FORBIDDEN_403);
}
public boolean isResponse404() {
return responseLineStartsWith(FAIL_404);
}
public boolean isResponse405() {
return responseLineStartsWith(FAIL_405);
}
public boolean isResponse408() {
return responseLineStartsWith(TIMEOUT_408);
}
public boolean isResponse413() {
return responseLineStartsWith(FAIL_413);
}
public boolean isResponse417() {
return responseLineStartsWith(FAIL_417);
}
public boolean isResponse50x() {
return responseLineStartsWith(FAIL_50X);
}
public boolean isResponse500() {
return responseLineStartsWith(FAIL_500);
}
public boolean isResponse501() {
return responseLineStartsWith(FAIL_501);
}
public Socket getSocket() {
return socket;
}
public abstract boolean isResponseBodyOK();
}

View File

@@ -0,0 +1,180 @@
/*
* 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 org.junit.Assert;
import org.junit.Test;
public class TestBootstrap {
@Test
public void testEmptyNonQuoted() {
doTest("");
}
@Test
public void testOneNonQuoted() {
doTest("a", "a");
}
@Test
public void testTwoNonQuoted01() {
doTest("a,b", "a", "b");
}
@Test
public void testTwoNonQuoted02() {
doTest("a,,b", "a", "b");
}
@Test
public void testTwoNonQuoted03() {
doTest(",a,b", "a", "b");
}
@Test
public void testTwoNonQuoted04() {
doTest("a,b,", "a", "b");
}
@Test
public void testThreeNonQuoted() {
doTest("a,b,c", "a", "b", "c");
}
@Test
public void testEmptyQuoted() {
doTest("\"\"");
}
@Test
public void testOneQuoted01() {
doTest("\"a\"", "a");
}
@Test
public void testOneQuoted02() {
doTest("\"aaa\"", "aaa");
}
@Test
public void testOneQuoted03() {
doTest("\"a,aa\"", "a,aa");
}
@Test
public void testOneQuoted04() {
doTest("\",aaa\"", ",aaa");
}
@Test
public void testOneQuoted05() {
doTest("\"aaa,\"", "aaa,");
}
@Test
public void testTwoQuoted01() {
doTest("\"aaa\",bbb", "aaa", "bbb");
}
@Test
public void testTwoQuoted02() {
doTest("\"a,aa\",bbb", "a,aa", "bbb");
}
@Test
public void testTwoQuoted03() {
doTest("\"aaa\",\"bbb\"", "aaa", "bbb");
}
@Test
public void testTwoQuoted04() {
doTest("\"aaa\",\",bbb\"", "aaa", ",bbb");
}
@Test
public void testTwoQuoted05() {
doTest("aaa,\"bbb,\"", "aaa", "bbb,");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes01() {
doTest("\"", "ignored");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes02() {
doTest("\"aaa", "ignored");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes03() {
doTest("aaa\"", "ignored");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes04() {
doTest("a\"a", "ignored");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes05() {
doTest("b,\"", "ignored");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes06() {
doTest("b,\"aaa", "ignored");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes07() {
doTest("b,aaa\"", "ignored");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes08() {
doTest("b,a\"a", "ignored");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes09() {
doTest("\",b", "ignored");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes10() {
doTest("\"aaa,b", "ignored");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes11() {
doTest("aaa\",b", "ignored");
}
@Test(expected=IllegalArgumentException.class)
public void testUnbalancedQuotes12() {
doTest("a\"a,b", "ignored");
}
private void doTest(String input, String... expected) {
String[] result = Bootstrap.getPaths(input);
Assert.assertArrayEquals(expected, result);
}
}

View File

@@ -0,0 +1,206 @@
/*
* 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.util.Set;
import javax.servlet.Servlet;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Assert;
import org.junit.Test;
import org.apache.catalina.Context;
import org.apache.catalina.core.StandardContext;
import org.apache.tomcat.util.buf.ByteChunk;
public class TestContextConfig extends TomcatBaseTest {
@Test
public void testOverrideWithSCIDefaultName() throws Exception {
doTestOverrideDefaultServletWithSCI("default");
}
@Test
public void testOverrideWithSCIDefaultMapping() throws Exception {
doTestOverrideDefaultServletWithSCI("anything");
}
private void doTestOverrideDefaultServletWithSCI(String servletName)
throws Exception{
Tomcat tomcat = getTomcatInstance();
File appDir = new File("test/webapp");
StandardContext ctxt = (StandardContext) tomcat.addContext(null,
"/test", appDir.getAbsolutePath());
ctxt.setDefaultWebXml(new File("conf/web.xml").getAbsolutePath());
ctxt.addLifecycleListener(new ContextConfig());
ctxt.addServletContainerInitializer(
new CustomDefaultServletSCI(servletName), null);
tomcat.start();
assertPageContains("/test", "OK - Custom default Servlet");
}
@Test
public void testBug51396() throws Exception {
Tomcat tomcat = getTomcatInstance();
File appDir = new File("test/webapp-fragments");
// app dir is relative to server home
Context ctx = tomcat.addWebapp(null, "/test", appDir.getAbsolutePath());
skipTldsForResourceJars(ctx);
tomcat.start();
assertPageContains("/test/bug51396.jsp", "<p>OK</p>");
}
@Test
public void testBug53574() throws Exception {
getTomcatInstanceTestWebapp(false, true);
assertPageContains("/test/bug53574", "OK");
}
@Test
public void testBug54262() throws Exception {
Tomcat tomcat = getTomcatInstance();
File appDir = new File("test/webapp-fragments-empty-absolute-ordering");
tomcat.addWebapp(null, "/test", appDir.getAbsolutePath());
tomcat.start();
assertPageContains("/test/resourceA.jsp",
"resourceA.jsp in resources.jar");
assertPageContains("/test/resources/HelloWorldExample",
null, HttpServletResponse.SC_NOT_FOUND);
}
@Test
public void testBug54379() throws Exception {
Tomcat tomcat = getTomcatInstance();
File appDir = new File("test/webapp-fragments");
Context context =
tomcat.addWebapp(null, "/test", appDir.getAbsolutePath());
Tomcat.addServlet(context, "TestServlet",
"org.apache.catalina.startup.TesterServletWithLifeCycleMethods");
context.addServletMappingDecoded("/testServlet", "TestServlet");
tomcat.enableNaming();
tomcat.start();
assertPageContains("/test/testServlet", "postConstruct1()");
}
@Test
public void testBug54448and54450() throws Exception {
Tomcat tomcat = getTomcatInstance();
File appDir = new File("test/webapp-fragments");
Context context = tomcat.addWebapp(null, "/test",
appDir.getAbsolutePath());
Tomcat.addServlet(context, "TestServlet",
"org.apache.catalina.startup.TesterServletWithAnnotations");
context.addServletMappingDecoded("/testServlet", "TestServlet");
tomcat.enableNaming();
tomcat.start();
assertPageContains("/test/testServlet",
"envEntry1: 0 envEntry2: 2 envEntry3: 33 envEntry4: 0 envEntry5: 55 envEntry6: 66");
}
@Test
public void testBug55210() throws Exception {
Tomcat tomcat = getTomcatInstance();
File appDir = new File("test/webapp-fragments");
tomcat.addWebapp(null, "/test", appDir.getAbsolutePath());
tomcat.start();
assertPageContains("/test/TesterServlet1", "OK");
assertPageContains("/test/TesterServlet2", "OK");
}
private static class CustomDefaultServletSCI
implements ServletContainerInitializer {
private String servletName;
public CustomDefaultServletSCI(String servletName) {
this.servletName = servletName;
}
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx)
throws ServletException {
Servlet s = new CustomDefaultServlet();
ServletRegistration.Dynamic r = ctx.addServlet(servletName, s);
r.addMapping("/");
}
}
private static class CustomDefaultServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
resp.getWriter().print("OK - Custom default Servlet");
}
}
private void assertPageContains(String pageUrl, String expectedBody)
throws IOException {
assertPageContains(pageUrl, expectedBody, HttpServletResponse.SC_OK);
}
private void assertPageContains(String pageUrl, String expectedBody,
int expectedStatus) throws IOException {
ByteChunk res = new ByteChunk();
int sc = getUrl("http://localhost:" + getPort() + pageUrl, res, null);
Assert.assertEquals(expectedStatus, sc);
if (expectedStatus == HttpServletResponse.SC_OK) {
String result = res.toString();
Assert.assertTrue(result, result.indexOf(expectedBody) > -1);
}
}
}

View File

@@ -0,0 +1,372 @@
/*
* 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.beans.PropertyChangeListener;
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.DispatcherType;
import javax.servlet.Servlet;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.junit.Assert;
import org.junit.Test;
import org.apache.catalina.Context;
import org.apache.catalina.Loader;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.ContextConfig.JavaClassCacheEntry;
import org.apache.tomcat.util.descriptor.web.FilterDef;
import org.apache.tomcat.util.descriptor.web.FilterMap;
import org.apache.tomcat.util.descriptor.web.ServletDef;
import org.apache.tomcat.util.descriptor.web.WebXml;
/**
* Check Servlet 3.0 Spec 8.2.3.3: Override annotation parameter from web.xml or
* fragment.
*
* @author Peter Rossbach
*/
public class TestContextConfigAnnotation {
@Test
public void testAnnotation() throws Exception {
WebXml webxml = new WebXml();
Map<String,JavaClassCacheEntry> javaClassCache = new HashMap<>();
ContextConfig config = new ContextConfig();
File pFile = paramClassResource(
"org/apache/catalina/startup/ParamServlet");
Assert.assertTrue(pFile.exists());
config.processAnnotationsFile(pFile, webxml, false, javaClassCache);
ServletDef servletDef = webxml.getServlets().get("param");
Assert.assertNotNull(servletDef);
Assert.assertEquals("Hello", servletDef.getParameterMap().get("foo"));
Assert.assertEquals("World!", servletDef.getParameterMap().get("bar"));
Assert.assertEquals("param", webxml.getServletMappings().get(
"/annotation/overwrite"));
Assert.assertEquals("param", servletDef.getDescription());
Assert.assertEquals("param", servletDef.getDisplayName());
Assert.assertEquals("paramLarge.png", servletDef.getLargeIcon());
Assert.assertEquals("paramSmall.png", servletDef.getSmallIcon());
Assert.assertEquals(Boolean.FALSE, servletDef.getAsyncSupported());
Assert.assertEquals(Integer.valueOf(0), servletDef.getLoadOnStartup());
Assert.assertNull(servletDef.getEnabled());
Assert.assertNull(servletDef.getJspFile());
}
@Test
public void testOverwriteAnnotation() throws Exception {
WebXml webxml = new WebXml();
Map<String,JavaClassCacheEntry> javaClassCache = new HashMap<>();
ServletDef servletDef = new ServletDef();
servletDef.setServletName("param");
servletDef.setServletClass("org.apache.catalina.startup.ParamServlet");
servletDef.addInitParameter("foo", "tomcat");
servletDef.setDescription("Description");
servletDef.setDisplayName("DisplayName");
servletDef.setLargeIcon("LargeIcon");
servletDef.setSmallIcon("SmallIcon");
servletDef.setAsyncSupported("true");
servletDef.setLoadOnStartup("1");
webxml.addServlet(servletDef);
webxml.addServletMapping("/param", "param");
ContextConfig config = new ContextConfig();
File pFile = paramClassResource(
"org/apache/catalina/startup/ParamServlet");
Assert.assertTrue(pFile.exists());
config.processAnnotationsFile(pFile, webxml, false, javaClassCache);
Assert.assertEquals(servletDef, webxml.getServlets().get("param"));
Assert.assertEquals("tomcat", servletDef.getParameterMap().get("foo"));
Assert.assertEquals("param", webxml.getServletMappings().get("/param"));
// annotation mapping not added s. Servlet Spec 3.0 (Nov 2009)
// 8.2.3.3.iv page 81
Assert.assertNull(webxml.getServletMappings().get("/annotation/overwrite"));
Assert.assertEquals("Description", servletDef.getDescription());
Assert.assertEquals("DisplayName", servletDef.getDisplayName());
Assert.assertEquals("LargeIcon", servletDef.getLargeIcon());
Assert.assertEquals("SmallIcon", servletDef.getSmallIcon());
Assert.assertEquals(Boolean.TRUE, servletDef.getAsyncSupported());
Assert.assertEquals(Integer.valueOf(1), servletDef.getLoadOnStartup());
Assert.assertNull(servletDef.getEnabled());
Assert.assertNull(servletDef.getJspFile());
}
@Test
public void testNoMapping() throws Exception {
WebXml webxml = new WebXml();
Map<String,JavaClassCacheEntry> javaClassCache = new HashMap<>();
ContextConfig config = new ContextConfig();
File pFile = paramClassResource(
"org/apache/catalina/startup/NoMappingParamServlet");
Assert.assertTrue(pFile.exists());
config.processAnnotationsFile(pFile, webxml, false, javaClassCache);
ServletDef servletDef = webxml.getServlets().get("param1");
Assert.assertNull(servletDef);
webxml.addServletMapping("/param", "param1");
config.processAnnotationsFile(pFile, webxml, false, javaClassCache);
servletDef = webxml.getServlets().get("param1");
Assert.assertNull(servletDef);
}
@Test
public void testSetupWebXMLNoMapping() throws Exception {
WebXml webxml = new WebXml();
Map<String,JavaClassCacheEntry> javaClassCache = new HashMap<>();
ServletDef servletDef = new ServletDef();
servletDef.setServletName("param1");
servletDef.setServletClass(
"org.apache.catalina.startup.NoMappingParamServlet");
servletDef.addInitParameter("foo", "tomcat");
webxml.addServlet(servletDef);
webxml.addServletMapping("/param", "param1");
ContextConfig config = new ContextConfig();
File pFile = paramClassResource(
"org/apache/catalina/startup/NoMappingParamServlet");
Assert.assertTrue(pFile.exists());
config.processAnnotationsFile(pFile, webxml, false, javaClassCache);
Assert.assertEquals("tomcat", servletDef.getParameterMap().get("foo"));
Assert.assertEquals("World!", servletDef.getParameterMap().get("bar"));
ServletDef servletDef1 = webxml.getServlets().get("param1");
Assert.assertNotNull(servletDef1);
Assert.assertEquals(servletDef, servletDef1);
}
@Test
public void testDuplicateMapping() throws Exception {
WebXml webxml = new WebXml();
Map<String,JavaClassCacheEntry> javaClassCache = new HashMap<>();
ContextConfig config = new ContextConfig();
File pFile = paramClassResource(
"org/apache/catalina/startup/DuplicateMappingParamServlet");
Assert.assertTrue(pFile.exists());
try {
config.processAnnotationsFile(pFile, webxml, false, javaClassCache);
Assert.fail();
} catch (IllegalArgumentException ex) {
// ignore
}
ServletDef servletDef = webxml.getServlets().get("param");
Assert.assertNull(servletDef);
}
@Test
public void testFilterMapping() throws Exception {
WebXml webxml = new WebXml();
Map<String,JavaClassCacheEntry> javaClassCache = new HashMap<>();
ContextConfig config = new ContextConfig();
File sFile = paramClassResource(
"org/apache/catalina/startup/ParamServlet");
config.processAnnotationsFile(sFile, webxml, false, javaClassCache);
File fFile = paramClassResource(
"org/apache/catalina/startup/ParamFilter");
config.processAnnotationsFile(fFile, webxml, false, javaClassCache);
FilterDef fdef = webxml.getFilters().get("paramFilter");
Assert.assertNotNull(fdef);
Assert.assertEquals("Servlet says: ",fdef.getParameterMap().get("message"));
}
@Test
public void testOverwriteFilterMapping() throws Exception {
WebXml webxml = new WebXml();
Map<String,JavaClassCacheEntry> javaClassCache = new HashMap<>();
FilterDef filterDef = new FilterDef();
filterDef.setFilterName("paramFilter");
filterDef.setFilterClass("org.apache.catalina.startup.ParamFilter");
filterDef.addInitParameter("message", "tomcat");
filterDef.setDescription("Description");
filterDef.setDisplayName("DisplayName");
filterDef.setLargeIcon("LargeIcon");
filterDef.setSmallIcon("SmallIcon");
filterDef.setAsyncSupported("true");
webxml.addFilter(filterDef);
FilterMap filterMap = new FilterMap();
filterMap.addURLPatternDecoded("/param1");
filterMap.setFilterName("paramFilter");
webxml.addFilterMapping(filterMap);
ContextConfig config = new ContextConfig();
File sFile = paramClassResource(
"org/apache/catalina/startup/ParamServlet");
config.processAnnotationsFile(sFile, webxml, false, javaClassCache);
File fFile = paramClassResource(
"org/apache/catalina/startup/ParamFilter");
config.processAnnotationsFile(fFile, webxml, false, javaClassCache);
FilterDef fdef = webxml.getFilters().get("paramFilter");
Assert.assertNotNull(fdef);
Assert.assertEquals(filterDef,fdef);
Assert.assertEquals("tomcat",fdef.getParameterMap().get("message"));
Set<FilterMap> filterMappings = webxml.getFilterMappings();
Assert.assertTrue(filterMappings.contains(filterMap));
// annotation mapping not added s. Servlet Spec 3.0 (Nov 2009)
// 8.2.3.3.vi page 81
String[] urlPatterns = filterMap.getURLPatterns();
Assert.assertNotNull(urlPatterns);
Assert.assertEquals(1,urlPatterns.length);
Assert.assertEquals("/param1",urlPatterns[0]);
// check simple Parameter
Assert.assertEquals("Description", fdef.getDescription());
Assert.assertEquals("DisplayName", fdef.getDisplayName());
Assert.assertEquals("LargeIcon", fdef.getLargeIcon());
Assert.assertEquals("SmallIcon", fdef.getSmallIcon());
// FIXME: Strange why servletDef is Boolean and FilterDef is String?
Assert.assertEquals("true", fdef.getAsyncSupported());
String[] dis = filterMap.getDispatcherNames();
Assert.assertEquals(2, dis.length);
Assert.assertEquals(DispatcherType.ERROR.toString(),dis[0]);
Assert.assertEquals(DispatcherType.ASYNC.toString(),dis[1]);
}
@Test
public void testDuplicateFilterMapping() throws Exception {
WebXml webxml = new WebXml();
Map<String,JavaClassCacheEntry> javaClassCache = new HashMap<>();
ContextConfig config = new ContextConfig();
File pFile = paramClassResource(
"org/apache/catalina/startup/DuplicateMappingParamFilter");
Assert.assertTrue(pFile.exists());
try {
config.processAnnotationsFile(pFile, webxml, false, javaClassCache);
Assert.fail();
} catch (IllegalArgumentException ex) {
// ignore
}
FilterDef filterDef = webxml.getFilters().get("paramD");
Assert.assertNull(filterDef);
}
@Test
public void testCheckHandleTypes() throws Exception {
Map<String,JavaClassCacheEntry> javaClassCache = new HashMap<>();
ContextConfig config = new ContextConfig();
config.handlesTypesAnnotations = true;
config.handlesTypesNonAnnotations = true;
// Need a Context, Loader and ClassLoader for checkHandleTypes
StandardContext context = new StandardContext();
context.setLoader(new TesterLoader());
config.context = context;
// Add an SCI that has no interest in any type
SCI sciNone = new SCI();
config.initializerClassMap.put(sciNone, new HashSet<Class<?>>());
// Add an SCI with an interest in Servlets
SCI sciServlet = new SCI();
config.initializerClassMap.put(sciServlet, new HashSet<Class<?>>());
config.typeInitializerMap.put(Servlet.class,
new HashSet<ServletContainerInitializer>());
config.typeInitializerMap.get(Servlet.class).add(sciServlet);
// Add an SCI with an interest in Objects - i.e. everything
SCI sciObject = new SCI();
config.initializerClassMap.put(sciObject, new HashSet<Class<?>>());
config.typeInitializerMap.put(Object.class,
new HashSet<ServletContainerInitializer>());
config.typeInitializerMap.get(Object.class).add(sciObject);
// Scan Servlet, Filter, Servlet, Listener
WebXml ignore = new WebXml();
File file = paramClassResource(
"org/apache/catalina/startup/ParamServlet");
config.processAnnotationsFile(file, ignore, false, javaClassCache);
file = paramClassResource("org/apache/catalina/startup/ParamFilter");
config.processAnnotationsFile(file, ignore, false, javaClassCache);
file = paramClassResource("org/apache/catalina/startup/TesterServlet");
config.processAnnotationsFile(file, ignore, false, javaClassCache);
file = paramClassResource("org/apache/catalina/startup/TestListener");
config.processAnnotationsFile(file, ignore, false, javaClassCache);
// Check right number of classes were noted to be handled
Assert.assertEquals(0, config.initializerClassMap.get(sciNone).size());
Assert.assertEquals(2, config.initializerClassMap.get(sciServlet).size());
Assert.assertEquals(4, config.initializerClassMap.get(sciObject).size());
}
private static final class SCI implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx)
throws ServletException {
// NO-OP. Just need a class that implements SCI.
}
}
private static final class TesterLoader implements Loader {
@Override
public void backgroundProcess() {}
@Override
public ClassLoader getClassLoader() {
return this.getClass().getClassLoader();
}
@Override
public Context getContext() { return null; }
@Override
public void setContext(Context context) {}
@Override
public boolean getDelegate() { return false; }
@Override
public void setDelegate(boolean delegate) {}
@Override
public boolean getReloadable() { return false; }
@Override
public void setReloadable(boolean reloadable) {}
@Override
public void addPropertyChangeListener(PropertyChangeListener l) {
}
@Override
public boolean modified() { return false; }
@Override
public void removePropertyChangeListener(PropertyChangeListener l) {}
}
/**
* Find compiled test class
*
* @param className
* @return File Resource
* @throws URISyntaxException
*/
private File paramClassResource(String className) throws URISyntaxException {
URL url = getClass().getClassLoader().getResource(className + ".class");
Assert.assertNotNull(url);
File file = new File(url.toURI());
return file;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,124 @@
/*
* 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.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import org.junit.Assert;
import org.junit.Test;
import org.apache.catalina.Context;
public class TestListener extends TomcatBaseTest {
/*
* Check that a ServletContainerInitializer can install a
* {@link ServletContextListener} and that it gets initialized.
* @throws Exception
*/
@Test
public void testServletContainerInitializer() throws Exception {
Tomcat tomcat = getTomcatInstance();
// No file system docBase required
Context context = tomcat.addContext("", null);
context.addServletContainerInitializer(new SCI(), null);
tomcat.start();
Assert.assertTrue(SCL.initialized);
}
/*
* Check that a {@link ServletContextListener} cannot install a
* {@link ServletContainerInitializer}.
* @throws Exception
*/
@Test
public void testServletContextListener() throws Exception {
Tomcat tomcat = getTomcatInstance();
// No file system docBase required
Context context = tomcat.addContext("", null);
// SCL2 pretends to be in web.xml, and tries to install a
// ServletContainerInitializer.
context.addApplicationListener(SCL2.class.getName());
tomcat.start();
//check that the ServletContainerInitializer wasn't initialized.
Assert.assertFalse(SCL3.initialized);
}
public static class SCI implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx)
throws ServletException {
ctx.addListener(new SCL());
}
}
public static class SCL implements ServletContextListener {
static boolean initialized = false;
@Override
public void contextInitialized(ServletContextEvent sce) {
initialized = true;
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// NOOP
}
}
public static class SCL2 implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext sc = sce.getServletContext();
sc.addListener(SCL3.class.getName());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// NOOP
}
}
public static class SCL3 implements ServletContextListener {
static boolean initialized = false;
@Override
public void contextInitialized(ServletContextEvent sce) {
initialized = true;
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// NOOP
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,109 @@
/*
* 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.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLClassLoader;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Assert;
import org.junit.Test;
import org.apache.catalina.Context;
import org.apache.catalina.loader.WebappClassLoaderBase;
import org.apache.tomcat.util.buf.ByteChunk;
public class TestTomcatClassLoader extends TomcatBaseTest {
@Test
public void testDefaultClassLoader() throws Exception {
Tomcat tomcat = getTomcatInstance();
// No file system docBase required
Context ctx = tomcat.addContext("", null);
Tomcat.addServlet(ctx, "ClassLoaderReport", new ClassLoaderReport(null));
ctx.addServletMappingDecoded("/", "ClassLoaderReport");
tomcat.start();
ByteChunk res = getUrl("http://localhost:" + getPort() + "/");
Assert.assertEquals("WEBAPP,SYSTEM,OTHER,", res.toString());
}
@Test
public void testNonDefaultClassLoader() throws Exception {
ClassLoader cl = new URLClassLoader(new URL[0],
Thread.currentThread().getContextClassLoader());
Thread.currentThread().setContextClassLoader(cl);
Tomcat tomcat = getTomcatInstance();
tomcat.getServer().setParentClassLoader(cl);
// No file system docBase required
Context ctx = tomcat.addContext("", null);
Tomcat.addServlet(ctx, "ClassLoaderReport", new ClassLoaderReport(cl));
ctx.addServletMappingDecoded("/", "ClassLoaderReport");
tomcat.start();
ByteChunk res = getUrl("http://localhost:" + getPort() + "/");
Assert.assertEquals("WEBAPP,CUSTOM,SYSTEM,OTHER,", res.toString());
}
private static final class ClassLoaderReport extends HttpServlet {
private static final long serialVersionUID = 1L;
private transient ClassLoader custom;
public ClassLoaderReport(ClassLoader custom) {
this.custom = custom;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
ClassLoader system = ClassLoader.getSystemClassLoader();
ClassLoader cl = Thread.currentThread().getContextClassLoader();
while (cl != null) {
if (system == cl) {
out.print("SYSTEM,");
} else if (custom == cl) {
out.print("CUSTOM,");
} else if (cl instanceof WebappClassLoaderBase) {
out.print("WEBAPP,");
} else {
out.print("OTHER,");
}
cl = cl.getParent();
}
}
}
}

View File

@@ -0,0 +1,224 @@
/*
* 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.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.webresources.StandardRoot;
import org.apache.tomcat.unittest.TesterContext;
import org.easymock.EasyMock;
import org.easymock.IMocksControl;
public class TestWebappServiceLoader {
private static final String CONFIG_FILE =
"META-INF/services/javax.servlet.ServletContainerInitializer";
private IMocksControl control;
private ClassLoader cl;
private ClassLoader parent;
private Context context;
private ServletContext servletContext;
private WebappServiceLoader<ServletContainerInitializer> loader;
@Before
public void init() {
control = EasyMock.createStrictControl();
parent = control.createMock(ClassLoader.class);
cl = EasyMock.createMockBuilder(ClassLoader.class)
.withConstructor(parent)
.addMockedMethod("loadClass", String.class)
.createMock(control);
servletContext = control.createMock(ServletContext.class);
EasyMock.expect(servletContext.getClassLoader()).andStubReturn(cl);
context = new ExtendedTesterContext(servletContext, parent);
}
@Test
public void testNoInitializersFound() throws IOException {
loader = new WebappServiceLoader<>(context);
EasyMock.expect(servletContext.getAttribute(ServletContext.ORDERED_LIBS))
.andReturn(null);
EasyMock.expect(cl.getResources(CONFIG_FILE))
.andReturn(Collections.<URL>emptyEnumeration());
control.replay();
Assert.assertTrue(loader.load(ServletContainerInitializer.class).isEmpty());
control.verify();
}
@Test
@SuppressWarnings("unchecked")
public void testInitializerFromClasspath() throws IOException {
URL url = new URL("file://test");
loader = EasyMock.createMockBuilder(WebappServiceLoader.class)
.addMockedMethod("parseConfigFile", LinkedHashSet.class, URL.class)
.withConstructor(context).createMock(control);
EasyMock.expect(servletContext.getAttribute(ServletContext.ORDERED_LIBS))
.andReturn(null);
EasyMock.expect(cl.getResources(CONFIG_FILE))
.andReturn(Collections.enumeration(Collections.singleton(url)));
loader.parseConfigFile(EasyMock.isA(LinkedHashSet.class), EasyMock.same(url));
control.replay();
Assert.assertTrue(loader.load(ServletContainerInitializer.class).isEmpty());
control.verify();
}
@Test
@SuppressWarnings("unchecked")
public void testWithOrdering() throws IOException {
URL url1 = new URL("file://jar1.jar");
URL sci1 = new URL("jar:file://jar1.jar!/" + CONFIG_FILE);
URL url2 = new URL("file://dir/");
URL sci2 = new URL("file://dir/" + CONFIG_FILE);
loader = EasyMock.createMockBuilder(WebappServiceLoader.class)
.addMockedMethod("parseConfigFile", LinkedHashSet.class, URL.class)
.withConstructor(context).createMock(control);
List<String> jars = Arrays.asList("jar1.jar", "dir/");
EasyMock.expect(servletContext.getAttribute(ServletContext.ORDERED_LIBS))
.andReturn(jars);
EasyMock.expect(servletContext.getResource("/WEB-INF/classes/" + CONFIG_FILE))
.andReturn(null);
EasyMock.expect(servletContext.getResource("/WEB-INF/lib/jar1.jar"))
.andReturn(url1);
loader.parseConfigFile(EasyMock.isA(LinkedHashSet.class), EasyMock.eq(sci1));
EasyMock.expect(servletContext.getResource("/WEB-INF/lib/dir/"))
.andReturn(url2);
loader.parseConfigFile(EasyMock.isA(LinkedHashSet.class), EasyMock.eq(sci2));
EasyMock.expect(parent.getResources(CONFIG_FILE))
.andReturn(Collections.<URL>emptyEnumeration());
control.replay();
Assert.assertTrue(loader.load(ServletContainerInitializer.class).isEmpty());
control.verify();
}
@Test
public void testParseConfigFile() throws IOException {
LinkedHashSet<String> found = new LinkedHashSet<>();
loader = new WebappServiceLoader<>(context);
loader.parseConfigFile(found, getClass().getResource("service-config.txt"));
Assert.assertEquals(Collections.singleton("provider1"), found);
}
@Test
public void testLoadServices() throws Exception {
Class<?> sci = TesterServletContainerInitializer1.class;
loader = new WebappServiceLoader<>(context);
cl.loadClass(sci.getName());
EasyMock.expectLastCall()
.andReturn(sci);
LinkedHashSet<String> names = new LinkedHashSet<>();
names.add(sci.getName());
control.replay();
Collection<ServletContainerInitializer> initializers =
loader.loadServices(ServletContainerInitializer.class, names);
Assert.assertEquals(1, initializers.size());
Assert.assertTrue(sci.isInstance(initializers.iterator().next()));
control.verify();
}
@Test
public void testServiceIsNotExpectedType() throws Exception {
Class<?> sci = Object.class;
loader = new WebappServiceLoader<>(context);
cl.loadClass(sci.getName());
EasyMock.expectLastCall()
.andReturn(sci);
LinkedHashSet<String> names = new LinkedHashSet<>();
names.add(sci.getName());
control.replay();
try {
loader.loadServices(ServletContainerInitializer.class, names);
} catch (IOException e) {
Assert.assertTrue(e.getCause() instanceof ClassCastException);
} finally {
control.verify();
}
}
@Test
public void testServiceCannotBeConstructed() throws Exception {
Class<?> sci = Integer.class;
loader = new WebappServiceLoader<>(context);
cl.loadClass(sci.getName());
EasyMock.expectLastCall()
.andReturn(sci);
LinkedHashSet<String> names = new LinkedHashSet<>();
names.add(sci.getName());
control.replay();
try {
loader.loadServices(ServletContainerInitializer.class, names);
} catch (IOException e) {
Assert.assertTrue(e.getCause() instanceof ReflectiveOperationException);
} finally {
control.verify();
}
}
private static class ExtendedTesterContext extends TesterContext {
private final ServletContext servletContext;
private final ClassLoader parent;
private final WebResourceRoot resources;
public ExtendedTesterContext(ServletContext servletContext, ClassLoader parent) {
this.servletContext = servletContext;
this.parent = parent;
// Empty resources - any non-null returns will be mocked on the
// ServletContext
this.resources = new StandardRoot(this);
try {
this.resources.start();
} catch (LifecycleException e) {
throw new IllegalStateException(e);
}
}
@Override
public ServletContext getServletContext() {
return servletContext;
}
@Override
public String getContainerSciFilter() {
return "";
}
@Override
public ClassLoader getParentClassLoader() {
return parent;
}
@Override
public WebResourceRoot getResources() {
return resources;
}
}
}

View File

@@ -0,0 +1,66 @@
/*
* 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.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.catalina.realm.RealmBase;
/**
* Simple Realm that uses a configurable {@link Map} to link user names and
* passwords.
*/
public final class TesterMapRealm extends RealmBase {
private Map<String,String> users = new HashMap<>();
private Map<String,List<String>> roles = new HashMap<>();
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<>();
roles.put(username, userRoles);
}
userRoles.add(role);
}
@Override
@Deprecated
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));
}
}

View File

@@ -0,0 +1,39 @@
/*
* 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.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TesterServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
out.print("OK");
}
}

View File

@@ -0,0 +1,38 @@
/*
* 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.util.Set;
import javax.servlet.Servlet;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class TesterServletContainerInitializer1 implements
ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx)
throws ServletException {
Servlet s = new TesterServlet();
ServletRegistration.Dynamic r = ctx.addServlet("TesterServlet1", s);
r.addMapping("/TesterServlet1");
}
}

View File

@@ -0,0 +1,38 @@
/*
* 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.util.Set;
import javax.servlet.Servlet;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class TesterServletContainerInitializer2 implements
ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx)
throws ServletException {
Servlet s = new TesterServlet();
ServletRegistration.Dynamic r = ctx.addServlet("TesterServlet2", s);
r.addMapping("/TesterServlet2");
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A test servlet that will always encode the url in case the client requires
* session persistence but is not configured to support cookies.
*/
public class TesterServletEncodeUrl extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* Almost minimal processing for a servlet.
* <p>
* The request parameter <code>nextUrl</code> specifies the url to which the
* caller would like to go next. If supplied, put an encoded url into the
* returned html page as a hyperlink.
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
out.print("OK");
String param = req.getParameter("nextUrl");
if (param!=null) {
// append an encoded url to carry the sessionids
String targetUrl = resp.encodeURL(param);
out.print(". You want to go <a href=\"");
out.print(targetUrl);
out.print("\">here next</a>.");
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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.IOException;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TesterServletWithAnnotations extends HttpServlet {
private static final long serialVersionUID = 1L;
@Resource
private int envEntry1;
private int envEntry2;
private int envEntry3;
private int envEntry4;
@Resource(name = "envEntry5")
private int envEntry5;
private int envEntry6;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
resp.getWriter().print("envEntry1: " + envEntry1);
resp.getWriter().print(" envEntry2: " + envEntry2);
resp.getWriter().print(" envEntry3: " + envEntry3);
resp.getWriter().print(" envEntry4: " + envEntry4);
resp.getWriter().print(" envEntry5: " + envEntry5);
resp.getWriter().print(" envEntry6: " + envEntry6);
}
public void setEnvEntry2(int envEntry2) {
this.envEntry2 = envEntry2;
}
@Resource
public void setEnvEntry3(int envEntry3) {
this.envEntry3 = envEntry3;
}
@Resource
public void setEnvEntry4(int envEntry4) {
this.envEntry4 = envEntry4;
}
@Resource(name = "envEntry6")
public void setEnvEntry6(int envEntry6) {
this.envEntry6 = envEntry6;
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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.IOException;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TesterServletWithLifeCycleMethods extends HttpServlet {
private static final long serialVersionUID = 1L;
private String result;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
resp.getWriter().print(result);
}
@PostConstruct
protected void postConstruct() {
result = "postConstruct()";
}
@PreDestroy
protected void preDestroy() {
result = "preDestroy()";
}
protected void postConstruct1() {
result = "postConstruct1()";
}
protected void preDestroy1() {
result = "preDestroy1()";
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
# 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.
# This is a test file for the WebappServiceLoader
# It contains comment lines and blank lines
provider1 # This comment should be ignored
provider1 # provider 1 should only be returned once

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<post-construct>
<lifecycle-callback-class>test.TestServlet</lifecycle-callback-class>
<lifecycle-callback-method>postConstruct</lifecycle-callback-method>
</post-construct>
<pre-destroy>
<lifecycle-callback-class>test.TestServlet</lifecycle-callback-class>
<lifecycle-callback-method>preDestroy</lifecycle-callback-method>
</pre-destroy>
</web-app>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<absolute-ordering>
<name>bar</name>
</absolute-ordering>
</web-app>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<post-construct>
<lifecycle-callback-class>test.TestServlet</lifecycle-callback-class>
<lifecycle-callback-method>postConstruct1</lifecycle-callback-method>
</post-construct>
<post-construct>
<lifecycle-callback-class>test.TestServlet</lifecycle-callback-class>
<lifecycle-callback-method>postConstruct2</lifecycle-callback-method>
</post-construct>
</web-app>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<absolute-ordering>
<name>foo</name>
</absolute-ordering>
<absolute-ordering>
<name>bar</name>
</absolute-ordering>
</web-app>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
version="3.1"
metadata-complete="true">
<name>name1</name>
</web-fragment>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
version="3.1"
metadata-complete="true">
<ordering>
<before>
<name>bar</name>
</before>
</ordering>
</web-fragment>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
version="3.1"
metadata-complete="true">
<name>name1</name>
<name>name2</name>
</web-fragment>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
version="3.1"
metadata-complete="true">
<ordering>
<after>
<name>foo</name>
</after>
</ordering>
<ordering>
<before>
<name>bar</name>
</before>
</ordering>
</web-fragment>