init
This commit is contained in:
108
test/javax/servlet/annotation/TestServletSecurity.java
Normal file
108
test/javax/servlet/annotation/TestServletSecurity.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 javax.servlet.annotation;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
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.startup.Tomcat;
|
||||
import org.apache.catalina.startup.TomcatBaseTest;
|
||||
import org.apache.tomcat.util.buf.ByteChunk;
|
||||
|
||||
public class TestServletSecurity extends TomcatBaseTest {
|
||||
|
||||
@Test
|
||||
public void testFooThenFooBar() throws Exception {
|
||||
doTestFooAndFooBar(true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFooBarThenFoo() throws Exception {
|
||||
doTestFooAndFooBar(false);
|
||||
}
|
||||
|
||||
|
||||
public void doTestFooAndFooBar(boolean fooFirst) throws Exception {
|
||||
// Setup Tomcat instance
|
||||
Tomcat tomcat = getTomcatInstance();
|
||||
|
||||
// No file system docBase required
|
||||
Context ctx = tomcat.addContext("", null);
|
||||
|
||||
Tomcat.addServlet(ctx, "Foo", Foo.class.getName());
|
||||
ctx.addServletMappingDecoded("/foo/*", "Foo");
|
||||
|
||||
Tomcat.addServlet(ctx, "FooBar", FooBar.class.getName());
|
||||
ctx.addServletMappingDecoded("/foo/bar/*", "FooBar");
|
||||
|
||||
tomcat.start();
|
||||
|
||||
ByteChunk bc = new ByteChunk();
|
||||
int rc;
|
||||
|
||||
if (fooFirst) {
|
||||
rc = getUrl("http://localhost:" + getPort() + "/foo", bc, null, null);
|
||||
} else {
|
||||
rc = getUrl("http://localhost:" + getPort() + "/foo/bar", bc, null, null);
|
||||
}
|
||||
|
||||
bc.recycle();
|
||||
Assert.assertEquals(403, rc);
|
||||
|
||||
if (fooFirst) {
|
||||
rc = getUrl("http://localhost:" + getPort() + "/foo/bar", bc, null, null);
|
||||
} else {
|
||||
rc = getUrl("http://localhost:" + getPort() + "/foo", bc, null, null);
|
||||
}
|
||||
|
||||
Assert.assertEquals(403, rc);
|
||||
}
|
||||
|
||||
|
||||
@ServletSecurity(@HttpConstraint(ServletSecurity.EmptyRoleSemantic.DENY))
|
||||
public static class Foo extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.getWriter().print("OK: Foo");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class FooBar extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.getWriter().print("OK: FooBar");
|
||||
}
|
||||
}
|
||||
}
|
||||
247
test/javax/servlet/annotation/TestServletSecurityMappings.java
Normal file
247
test/javax/servlet/annotation/TestServletSecurityMappings.java
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* 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 javax.servlet.annotation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
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.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.catalina.startup.TomcatBaseTest;
|
||||
import org.apache.tomcat.util.buf.ByteChunk;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class TestServletSecurityMappings extends TomcatBaseTest {
|
||||
|
||||
@Parameters(name="{0}, {1}, {2}, {3}")
|
||||
public static Collection<Object[]> inputs() {
|
||||
List<Object[]> result = new ArrayList<>();
|
||||
result.add(new Object[] { Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE });
|
||||
result.add(new Object[] { Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, Boolean.TRUE });
|
||||
result.add(new Object[] { Boolean.FALSE, Boolean.FALSE, Boolean.TRUE , Boolean.FALSE });
|
||||
result.add(new Object[] { Boolean.FALSE, Boolean.FALSE, Boolean.TRUE, Boolean.TRUE });
|
||||
result.add(new Object[] { Boolean.FALSE, Boolean.TRUE, Boolean.FALSE, Boolean.FALSE });
|
||||
result.add(new Object[] { Boolean.FALSE, Boolean.TRUE, Boolean.FALSE, Boolean.TRUE });
|
||||
result.add(new Object[] { Boolean.FALSE, Boolean.TRUE, Boolean.TRUE , Boolean.FALSE });
|
||||
result.add(new Object[] { Boolean.FALSE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE });
|
||||
result.add(new Object[] { Boolean.TRUE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE });
|
||||
result.add(new Object[] { Boolean.TRUE, Boolean.FALSE, Boolean.FALSE, Boolean.TRUE });
|
||||
result.add(new Object[] { Boolean.TRUE, Boolean.FALSE, Boolean.TRUE , Boolean.FALSE });
|
||||
result.add(new Object[] { Boolean.TRUE, Boolean.FALSE, Boolean.TRUE, Boolean.TRUE });
|
||||
result.add(new Object[] { Boolean.TRUE, Boolean.TRUE, Boolean.FALSE, Boolean.FALSE });
|
||||
result.add(new Object[] { Boolean.TRUE, Boolean.TRUE, Boolean.FALSE, Boolean.TRUE });
|
||||
result.add(new Object[] { Boolean.TRUE, Boolean.TRUE, Boolean.TRUE , Boolean.FALSE });
|
||||
result.add(new Object[] { Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE });
|
||||
return result;
|
||||
}
|
||||
|
||||
@Parameter(0)
|
||||
public boolean redirectContextRoot;
|
||||
|
||||
@Parameter(1)
|
||||
public boolean secureRoot;
|
||||
|
||||
@Parameter(2)
|
||||
public boolean secureDefault;
|
||||
|
||||
@Parameter(3)
|
||||
public boolean secureFoo;
|
||||
|
||||
|
||||
@Test
|
||||
public void doTestSecurityAnnotationsAddServlet() throws Exception {
|
||||
|
||||
// Setup Tomcat instance
|
||||
Tomcat tomcat = getTomcatInstance();
|
||||
|
||||
// No file system docBase required
|
||||
Context ctx = tomcat.addContext("/test", null);
|
||||
ctx.setMapperContextRootRedirectEnabled(redirectContextRoot);
|
||||
|
||||
ServletContainerInitializer sci = new SCI(secureRoot, secureDefault, secureFoo);
|
||||
ctx.addServletContainerInitializer(sci, null);
|
||||
|
||||
tomcat.start();
|
||||
|
||||
ByteChunk bc = new ByteChunk();
|
||||
int rc;
|
||||
|
||||
// Foo
|
||||
rc = getUrl("http://localhost:" + getPort() + "/test/foo", bc, false);
|
||||
if (secureFoo || secureDefault) {
|
||||
Assert.assertEquals(403, rc);
|
||||
} else {
|
||||
Assert.assertEquals(200, rc);
|
||||
}
|
||||
bc.recycle();
|
||||
|
||||
// Default
|
||||
rc = getUrl("http://localhost:" + getPort() + "/test/something", bc, false);
|
||||
if (secureDefault) {
|
||||
Assert.assertEquals(403, rc);
|
||||
} else {
|
||||
Assert.assertEquals(200, rc);
|
||||
}
|
||||
bc.recycle();
|
||||
|
||||
// Root
|
||||
rc = getUrl("http://localhost:" + getPort() + "/test", bc, false);
|
||||
if (redirectContextRoot) {
|
||||
Assert.assertEquals(302, rc);
|
||||
} else {
|
||||
if (secureRoot || secureDefault) {
|
||||
Assert.assertEquals(403, rc);
|
||||
} else {
|
||||
Assert.assertEquals(200, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class SCI implements ServletContainerInitializer {
|
||||
|
||||
private final boolean secureRoot;
|
||||
private final boolean secureDefault;
|
||||
private final boolean secureFoo;
|
||||
|
||||
public SCI(boolean secureRoot, boolean secureDefault, boolean secureFoo) {
|
||||
this.secureRoot = secureRoot;
|
||||
this.secureDefault = secureDefault;
|
||||
this.secureFoo = secureFoo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartup(Set<Class<?>> c, ServletContext ctx)
|
||||
throws ServletException {
|
||||
|
||||
ServletRegistration.Dynamic sr;
|
||||
if (secureRoot) {
|
||||
sr = ctx.addServlet("Root", SecureRoot.class.getName());
|
||||
} else {
|
||||
sr =ctx.addServlet("Root", Root.class.getName());
|
||||
}
|
||||
sr.addMapping("");
|
||||
|
||||
if (secureDefault) {
|
||||
sr = ctx.addServlet("Default", SecureDefault.class.getName());
|
||||
} else {
|
||||
sr = ctx.addServlet("Default", Default.class.getName());
|
||||
}
|
||||
sr.addMapping("/");
|
||||
|
||||
if (secureFoo) {
|
||||
sr = ctx.addServlet("Foo", SecureFoo.class.getName());
|
||||
} else {
|
||||
sr = ctx.addServlet("Foo", Foo.class.getName());
|
||||
}
|
||||
sr.addMapping("/foo");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ServletSecurity(@HttpConstraint(ServletSecurity.EmptyRoleSemantic.DENY))
|
||||
public static class SecureRoot extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.getWriter().print("OK");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Root extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.getWriter().print("OK");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ServletSecurity(@HttpConstraint(ServletSecurity.EmptyRoleSemantic.DENY))
|
||||
public static class SecureDefault extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.getWriter().print("OK");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Default extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.getWriter().print("OK");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ServletSecurity(@HttpConstraint(ServletSecurity.EmptyRoleSemantic.DENY))
|
||||
public static class SecureFoo extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.getWriter().print("OK");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Foo extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.getWriter().print("OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
153
test/javax/servlet/http/TestCookie.java
Normal file
153
test/javax/servlet/http/TestCookie.java
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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 javax.servlet.http;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Basic tests for Cookie in default configuration.
|
||||
*/
|
||||
public class TestCookie {
|
||||
public static final BitSet CHAR; // <any US-ASCII character (octets 0 - 127)>
|
||||
public static final BitSet CTL; // <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
||||
public static final BitSet SEPARATORS;
|
||||
public static final BitSet TOKEN; // 1*<any CHAR except CTLs or separators>
|
||||
|
||||
static {
|
||||
CHAR = new BitSet(256);
|
||||
CHAR.set(0, 128);
|
||||
|
||||
CTL = new BitSet(256);
|
||||
CTL.set(0, 32);
|
||||
CTL.set(127);
|
||||
|
||||
SEPARATORS = new BitSet(256);
|
||||
for (char ch : "()<>@,;:\\\"/[]?={} \t".toCharArray()) {
|
||||
SEPARATORS.set(ch);
|
||||
}
|
||||
|
||||
TOKEN = new BitSet(256);
|
||||
TOKEN.or(CHAR); // any CHAR
|
||||
TOKEN.andNot(CTL); // except CTLs
|
||||
TOKEN.andNot(SEPARATORS); // or separators
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaults() {
|
||||
Cookie cookie = new Cookie("foo", null);
|
||||
Assert.assertEquals("foo", cookie.getName());
|
||||
Assert.assertNull(cookie.getValue());
|
||||
Assert.assertEquals(0, cookie.getVersion());
|
||||
Assert.assertEquals(-1, cookie.getMaxAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitialValue() {
|
||||
Cookie cookie = new Cookie("foo", "bar");
|
||||
Assert.assertEquals("foo", cookie.getName());
|
||||
Assert.assertEquals("bar", cookie.getValue());
|
||||
Assert.assertEquals(0, cookie.getVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultImpliesNetscape() {
|
||||
// $Foo is allowed by Netscape but not by RFC2109
|
||||
Cookie cookie = new Cookie("$Foo", null);
|
||||
Assert.assertEquals("$Foo", cookie.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tokenVersion() {
|
||||
Cookie cookie = new Cookie("Version", null);
|
||||
Assert.assertEquals("Version", cookie.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attributeVersion() {
|
||||
Cookie cookie = new Cookie("Comment", null);
|
||||
Assert.assertEquals("Comment", cookie.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attributeDiscard() {
|
||||
Cookie cookie = new Cookie("Discard", null);
|
||||
Assert.assertEquals("Discard", cookie.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attributeExpires() {
|
||||
Cookie cookie = new Cookie("Expires", null);
|
||||
Assert.assertEquals("Expires", cookie.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attributeMaxAge() {
|
||||
Cookie cookie = new Cookie("Max-Age", null);
|
||||
Assert.assertEquals("Max-Age", cookie.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attributeDomain() {
|
||||
Cookie cookie = new Cookie("Domain", null);
|
||||
Assert.assertEquals("Domain", cookie.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attributePath() {
|
||||
Cookie cookie = new Cookie("Path", null);
|
||||
Assert.assertEquals("Path", cookie.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attributeSecure() {
|
||||
Cookie cookie = new Cookie("Secure", null);
|
||||
Assert.assertEquals("Secure", cookie.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attributeHttpOnly() {
|
||||
Cookie cookie = new Cookie("HttpOnly", null);
|
||||
Assert.assertEquals("HttpOnly", cookie.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void strictNamingImpliesRFC2109() {
|
||||
// Needs to be something RFC6265 allows, but strict naming does not.
|
||||
@SuppressWarnings("unused")
|
||||
Cookie cookie = new Cookie("$Foo", null);
|
||||
}
|
||||
|
||||
public static void checkCharInName(CookieNameValidator validator, BitSet allowed) {
|
||||
for (char ch = 0; ch < allowed.size(); ch++) {
|
||||
boolean expected = allowed.get(ch);
|
||||
String name = "X" + ch + "X";
|
||||
try {
|
||||
validator.validate(name);
|
||||
if (!expected) {
|
||||
Assert.fail(String.format("Char %d should not be allowed", Integer.valueOf(ch)));
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (expected) {
|
||||
Assert.fail(String.format("Char %d should be allowed", Integer.valueOf(ch)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
test/javax/servlet/http/TestCookieRFC2109Validator.java
Normal file
40
test/javax/servlet/http/TestCookieRFC2109Validator.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 javax.servlet.http;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Basic tests for Cookie in default configuration.
|
||||
*/
|
||||
public class TestCookieRFC2109Validator {
|
||||
static {
|
||||
System.setProperty("org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR", "true");
|
||||
}
|
||||
|
||||
private RFC2109Validator validator = new RFC2109Validator();
|
||||
|
||||
@Test
|
||||
public void actualCharactersAllowedInName() {
|
||||
TestCookie.checkCharInName(validator, TestCookie.TOKEN);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void leadingDollar() {
|
||||
validator.validate("$Version");
|
||||
}
|
||||
}
|
||||
40
test/javax/servlet/http/TestCookieRFC6265Validator.java
Normal file
40
test/javax/servlet/http/TestCookieRFC6265Validator.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 javax.servlet.http;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Basic tests for Cookie in default configuration.
|
||||
*/
|
||||
public class TestCookieRFC6265Validator {
|
||||
static {
|
||||
System.setProperty("org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR", "true");
|
||||
}
|
||||
|
||||
private RFC6265Validator validator = new RFC6265Validator();
|
||||
|
||||
@Test
|
||||
public void actualCharactersAllowedInName() {
|
||||
TestCookie.checkCharInName(validator, TestCookie.TOKEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void leadingDollar() {
|
||||
validator.validate("$Version");
|
||||
}
|
||||
}
|
||||
44
test/javax/servlet/http/TestCookieStrict.java
Normal file
44
test/javax/servlet/http/TestCookieStrict.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package javax.servlet.http;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Basic tests for Cookie in STRICT_SERVLET_COMPLIANCE configuration.
|
||||
*/
|
||||
public class TestCookieStrict {
|
||||
static {
|
||||
System.setProperty("org.apache.tomcat.util.http.ServerCookie.STRICT_NAMING", "true");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaults() {
|
||||
Cookie cookie = new Cookie("strict", null);
|
||||
Assert.assertEquals("strict", cookie.getName());
|
||||
Assert.assertNull(cookie.getValue());
|
||||
Assert.assertEquals(0, cookie.getVersion());
|
||||
Assert.assertEquals(-1, cookie.getMaxAge());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void strictNamingImpliesRFC2109() {
|
||||
@SuppressWarnings("unused")
|
||||
Cookie cookie = new Cookie("@Foo", null);
|
||||
}
|
||||
}
|
||||
207
test/javax/servlet/http/TestHttpServlet.java
Normal file
207
test/javax/servlet/http/TestHttpServlet.java
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* 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 javax.servlet.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.core.StandardContext;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.catalina.startup.TomcatBaseTest;
|
||||
import org.apache.tomcat.util.buf.ByteChunk;
|
||||
import org.apache.tomcat.util.collections.CaseInsensitiveKeyMap;
|
||||
|
||||
public class TestHttpServlet extends TomcatBaseTest {
|
||||
|
||||
@Test
|
||||
public void testBug53454() throws Exception {
|
||||
Tomcat tomcat = getTomcatInstance();
|
||||
|
||||
// No file system docBase required
|
||||
StandardContext ctx = (StandardContext) tomcat.addContext("", null);
|
||||
|
||||
// Map the test Servlet
|
||||
LargeBodyServlet largeBodyServlet = new LargeBodyServlet();
|
||||
Tomcat.addServlet(ctx, "largeBodyServlet", largeBodyServlet);
|
||||
ctx.addServletMappingDecoded("/", "largeBodyServlet");
|
||||
|
||||
tomcat.start();
|
||||
|
||||
Map<String,List<String>> resHeaders= new HashMap<>();
|
||||
int rc = headUrl("http://localhost:" + getPort() + "/", new ByteChunk(),
|
||||
resHeaders);
|
||||
|
||||
Assert.assertEquals(HttpServletResponse.SC_OK, rc);
|
||||
Assert.assertEquals(LargeBodyServlet.RESPONSE_LENGTH,
|
||||
resHeaders.get("Content-Length").get(0));
|
||||
}
|
||||
|
||||
|
||||
private static class LargeBodyServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String RESPONSE_LENGTH = "12345678901";
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.setHeader("content-length", RESPONSE_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Verifies that the same Content-Length is returned for both GET and HEAD
|
||||
* operations when a Servlet includes content from another Servlet
|
||||
*/
|
||||
@Test
|
||||
public void testBug57602() throws Exception {
|
||||
Tomcat tomcat = getTomcatInstance();
|
||||
|
||||
// No file system docBase required
|
||||
StandardContext ctx = (StandardContext) tomcat.addContext("", null);
|
||||
|
||||
Bug57602ServletOuter outer = new Bug57602ServletOuter();
|
||||
Tomcat.addServlet(ctx, "Bug57602ServletOuter", outer);
|
||||
ctx.addServletMappingDecoded("/outer", "Bug57602ServletOuter");
|
||||
|
||||
Bug57602ServletInner inner = new Bug57602ServletInner();
|
||||
Tomcat.addServlet(ctx, "Bug57602ServletInner", inner);
|
||||
ctx.addServletMappingDecoded("/inner", "Bug57602ServletInner");
|
||||
|
||||
tomcat.start();
|
||||
|
||||
Map<String,List<String>> resHeaders= new CaseInsensitiveKeyMap<>();
|
||||
String path = "http://localhost:" + getPort() + "/outer";
|
||||
ByteChunk out = new ByteChunk();
|
||||
|
||||
int rc = getUrl(path, out, resHeaders);
|
||||
Assert.assertEquals(HttpServletResponse.SC_OK, rc);
|
||||
String length = getSingleHeader("Content-Length", resHeaders);
|
||||
Assert.assertEquals(Long.parseLong(length), out.getLength());
|
||||
out.recycle();
|
||||
|
||||
rc = headUrl(path, out, resHeaders);
|
||||
Assert.assertEquals(HttpServletResponse.SC_OK, rc);
|
||||
Assert.assertEquals(0, out.getLength());
|
||||
Assert.assertEquals(length, resHeaders.get("Content-Length").get(0));
|
||||
|
||||
tomcat.stop();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testChunkingWithHead() throws Exception {
|
||||
Tomcat tomcat = getTomcatInstance();
|
||||
|
||||
// No file system docBase required
|
||||
StandardContext ctx = (StandardContext) tomcat.addContext("", null);
|
||||
|
||||
ChunkingServlet s = new ChunkingServlet();
|
||||
Tomcat.addServlet(ctx, "ChunkingServlet", s);
|
||||
ctx.addServletMappingDecoded("/chunking", "ChunkingServlet");
|
||||
|
||||
tomcat.start();
|
||||
|
||||
Map<String,List<String>> getHeaders = new CaseInsensitiveKeyMap<>();
|
||||
String path = "http://localhost:" + getPort() + "/chunking";
|
||||
ByteChunk out = new ByteChunk();
|
||||
|
||||
int rc = getUrl(path, out, getHeaders);
|
||||
Assert.assertEquals(HttpServletResponse.SC_OK, rc);
|
||||
out.recycle();
|
||||
|
||||
Map<String,List<String>> headHeaders = new HashMap<>();
|
||||
rc = headUrl(path, out, headHeaders);
|
||||
Assert.assertEquals(HttpServletResponse.SC_OK, rc);
|
||||
|
||||
// Headers should be the same (apart from Date)
|
||||
Assert.assertEquals(getHeaders.size(), headHeaders.size());
|
||||
for (Map.Entry<String, List<String>> getHeader : getHeaders.entrySet()) {
|
||||
String headerName = getHeader.getKey();
|
||||
if ("date".equalsIgnoreCase(headerName)) {
|
||||
continue;
|
||||
}
|
||||
Assert.assertTrue(headerName, headHeaders.containsKey(headerName));
|
||||
List<String> getValues = getHeader.getValue();
|
||||
List<String> headValues = headHeaders.get(headerName);
|
||||
Assert.assertEquals(getValues.size(), headValues.size());
|
||||
for (String value : getValues) {
|
||||
Assert.assertTrue(headValues.contains(value));
|
||||
}
|
||||
}
|
||||
|
||||
tomcat.stop();
|
||||
}
|
||||
|
||||
|
||||
private static class Bug57602ServletOuter extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.setContentType("text/plain");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
PrintWriter pw = resp.getWriter();
|
||||
pw.println("Header");
|
||||
req.getRequestDispatcher("/inner").include(req, resp);
|
||||
pw.println("Footer");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class Bug57602ServletInner extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.setContentType("text/plain");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
PrintWriter pw = resp.getWriter();
|
||||
pw.println("Included");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class ChunkingServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.setContentType("text/plain");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
PrintWriter pw = resp.getWriter();
|
||||
// Trigger chunking
|
||||
pw.write(new char[8192 * 16]);
|
||||
pw.println("Data");
|
||||
}
|
||||
}
|
||||
}
|
||||
366
test/javax/servlet/http/TestHttpServletResponseSendError.java
Normal file
366
test/javax/servlet/http/TestHttpServletResponseSendError.java
Normal file
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* 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 javax.servlet.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.Wrapper;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.catalina.startup.TomcatBaseTest;
|
||||
import org.apache.tomcat.util.buf.ByteChunk;
|
||||
import org.apache.tomcat.util.descriptor.web.ErrorPage;
|
||||
|
||||
/**
|
||||
* These tests evolved out of a discussion in the Jakarta Servlet project
|
||||
* regarding the intended behaviour in various error scenarios. Async requests
|
||||
* and/or async error pages added additional complexity.
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class TestHttpServletResponseSendError extends TomcatBaseTest {
|
||||
|
||||
/*
|
||||
* Implementation notes:
|
||||
* Original Request
|
||||
* - async
|
||||
* - error in original thread / new thread
|
||||
* - error before / after startAsync
|
||||
* - error before / after complete / dispatch
|
||||
* Error page
|
||||
* - sync
|
||||
* - async
|
||||
* - complete
|
||||
* - dispatch
|
||||
*/
|
||||
|
||||
private enum AsyncErrorPoint {
|
||||
/*
|
||||
* Thread A is the container thread the processes the original request.
|
||||
* Thread B is the async thread (may or may not be a container thread)
|
||||
* that is started by the async processing.
|
||||
*/
|
||||
THREAD_A_BEFORE_START_ASYNC,
|
||||
THREAD_A_AFTER_START_ASYNC,
|
||||
THREAD_A_AFTER_START_RUNNABLE,
|
||||
THREAD_B_BEFORE_COMPLETE
|
||||
/*
|
||||
* If the error is triggered after Thread B completes async processing
|
||||
* there is essentially a race condition between thread B making the
|
||||
* change and the container checking to see if the error flag has been
|
||||
* set. We can't easily control the execution order here so we don't
|
||||
* test it.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@Parameterized.Parameters(name = "{index}: async[{0}], throw[{1}], dispatch[{2}], errorPoint[{3}], useStart[{4}]")
|
||||
public static Collection<Object[]> parameters() {
|
||||
List<Object[]> parameterSets = new ArrayList<>();
|
||||
|
||||
for (Boolean async : booleans) {
|
||||
for (Boolean throwException : booleans) {
|
||||
if (async.booleanValue()) {
|
||||
for (Boolean useDispatch : booleans) {
|
||||
for (AsyncErrorPoint errorPoint : AsyncErrorPoint.values()) {
|
||||
for (Boolean useStart : booleans) {
|
||||
if (throwException.booleanValue() && !useStart.booleanValue() &&
|
||||
errorPoint == AsyncErrorPoint.THREAD_B_BEFORE_COMPLETE) {
|
||||
// Skip this combination as exceptions that occur on application
|
||||
// managed threads are not visible to the container.
|
||||
continue;
|
||||
}
|
||||
parameterSets.add(new Object[] { async, throwException, useDispatch,
|
||||
errorPoint, useStart} );
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Ignore the async specific parameters
|
||||
parameterSets.add(new Object[] { async, throwException, Boolean.FALSE,
|
||||
AsyncErrorPoint.THREAD_A_AFTER_START_ASYNC, Boolean.FALSE} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parameterSets;
|
||||
}
|
||||
|
||||
|
||||
@Parameter(0)
|
||||
public boolean async;
|
||||
@Parameter(1)
|
||||
public boolean throwException;
|
||||
@Parameter(2)
|
||||
public boolean useDispatch;
|
||||
@Parameter(3)
|
||||
public AsyncErrorPoint errorPoint;
|
||||
@Parameter(4)
|
||||
public boolean useStart;
|
||||
|
||||
|
||||
@Test
|
||||
public void testSendError() throws Exception {
|
||||
// Setup Tomcat instance
|
||||
Tomcat tomcat = getTomcatInstance();
|
||||
|
||||
// No file system docBase required
|
||||
Context ctx = tomcat.addContext("", null);
|
||||
|
||||
if (async) {
|
||||
Wrapper w = Tomcat.addServlet(ctx, "target",
|
||||
new TesterAsyncServlet(throwException, useDispatch, errorPoint, useStart));
|
||||
w.setAsyncSupported(true);
|
||||
} else {
|
||||
Tomcat.addServlet(ctx, "target", new TesterServlet(throwException));
|
||||
}
|
||||
ctx.addServletMappingDecoded("/target", "target");
|
||||
Tomcat.addServlet(ctx, "dispatch", new TesterDispatchServlet());
|
||||
ctx.addServletMappingDecoded("/dispatch", "dispatch");
|
||||
|
||||
Tomcat.addServlet(ctx, "error599", new ErrorServletStatic599());
|
||||
ctx.addServletMappingDecoded("/error599", "error599");
|
||||
Tomcat.addServlet(ctx, "errorException", new ErrorServletStaticException());
|
||||
ctx.addServletMappingDecoded("/errorException", "errorException");
|
||||
|
||||
ErrorPage ep1 = new ErrorPage();
|
||||
ep1.setErrorCode(599);
|
||||
ep1.setLocation("/error599");
|
||||
ctx.addErrorPage(ep1);
|
||||
|
||||
ErrorPage ep2 = new ErrorPage();
|
||||
ep2.setExceptionType(SendErrorException.class.getName());
|
||||
ep2.setLocation("/errorException");
|
||||
ctx.addErrorPage(ep2);
|
||||
|
||||
tomcat.start();
|
||||
|
||||
ByteChunk bc = new ByteChunk();
|
||||
int rc;
|
||||
|
||||
rc = getUrl("http://localhost:" + getPort() + "/target", bc, null, null);
|
||||
|
||||
String body = bc.toString();
|
||||
|
||||
if (throwException) {
|
||||
Assert.assertEquals(500, rc);
|
||||
Assert.assertEquals("FAIL-Exception", body);
|
||||
} else {
|
||||
Assert.assertEquals(599, rc);
|
||||
Assert.assertEquals("FAIL-599", body);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class TesterServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final boolean throwException;
|
||||
|
||||
public TesterServlet(boolean throwException) {
|
||||
this.throwException = throwException;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
if (throwException) {
|
||||
throw new SendErrorException();
|
||||
} else {
|
||||
// Custom 5xx code so we can detect if the correct error is
|
||||
// reported
|
||||
resp.sendError(599);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class TesterAsyncServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final boolean throwException;
|
||||
private final boolean useDispatch;
|
||||
private final AsyncErrorPoint errorPoint;
|
||||
private final boolean useStart;
|
||||
|
||||
public TesterAsyncServlet(boolean throwException, boolean useDispatch, AsyncErrorPoint errorPoint,
|
||||
boolean useStart) {
|
||||
this.throwException = throwException;
|
||||
this.useDispatch = useDispatch;
|
||||
this.errorPoint = errorPoint;
|
||||
this.useStart = useStart;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
|
||||
if (errorPoint == AsyncErrorPoint.THREAD_A_BEFORE_START_ASYNC) {
|
||||
doError(resp);
|
||||
}
|
||||
|
||||
AsyncContext ac = req.startAsync();
|
||||
ac.setTimeout(2000);
|
||||
|
||||
if (errorPoint == AsyncErrorPoint.THREAD_A_AFTER_START_ASYNC) {
|
||||
doError(resp);
|
||||
}
|
||||
|
||||
AsyncRunnable r = new AsyncRunnable(ac, throwException, useDispatch, errorPoint);
|
||||
|
||||
if (useStart) {
|
||||
ac.start(r);
|
||||
} else {
|
||||
Thread t = new Thread(r);
|
||||
t.start();
|
||||
}
|
||||
|
||||
if (errorPoint == AsyncErrorPoint.THREAD_A_AFTER_START_RUNNABLE) {
|
||||
doError(resp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void doError(HttpServletResponse resp) throws IOException {
|
||||
if (throwException) {
|
||||
throw new SendErrorException();
|
||||
} else {
|
||||
resp.sendError(599);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class AsyncRunnable implements Runnable {
|
||||
|
||||
private final AsyncContext ac;
|
||||
private final boolean throwException;
|
||||
private final boolean useDispatch;
|
||||
private final AsyncErrorPoint errorPoint;
|
||||
|
||||
public AsyncRunnable(AsyncContext ac, boolean throwException, boolean useDispatch,
|
||||
AsyncErrorPoint errorPoint) {
|
||||
this.ac = ac;
|
||||
this.throwException = throwException;
|
||||
this.useDispatch = useDispatch;
|
||||
this.errorPoint = errorPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
/*
|
||||
if (errorPoint == AsyncErrorPoint.THREAD_B_AFTER_COMPLETE) {
|
||||
if (useDispatch) {
|
||||
ac.complete();
|
||||
} else {
|
||||
ac.dispatch("/dispatch");
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (throwException) {
|
||||
throw new SendErrorException();
|
||||
} else {
|
||||
// Custom 5xx code so we can detect if the correct error is
|
||||
// reported
|
||||
try {
|
||||
((HttpServletResponse) ac.getResponse()).sendError(599);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (errorPoint == AsyncErrorPoint.THREAD_B_BEFORE_COMPLETE) {
|
||||
if (useDispatch) {
|
||||
ac.dispatch("/dispatch");
|
||||
} else {
|
||||
ac.complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class TesterDispatchServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.setContentType("text/plain");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
resp.getWriter().write("DISPATCH");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class SendErrorException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class ErrorServletStatic599 extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.setContentType("text/plain");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
resp.getWriter().write("FAIL-599");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ErrorServletStaticException extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.setContentType("text/plain");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
resp.getWriter().write("FAIL-Exception");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
37
test/javax/servlet/jsp/TestPageContext.java
Normal file
37
test/javax/servlet/jsp/TestPageContext.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 javax.servlet.jsp;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.startup.TomcatBaseTest;
|
||||
import org.apache.tomcat.util.buf.ByteChunk;
|
||||
|
||||
public class TestPageContext extends TomcatBaseTest {
|
||||
|
||||
@Test
|
||||
public void testBug49196() throws Exception {
|
||||
getTomcatInstanceTestWebapp(false, true);
|
||||
|
||||
ByteChunk res = getUrl("http://localhost:" + getPort() +
|
||||
"/test/bug49nnn/bug49196.jsp");
|
||||
|
||||
String result = res.toString();
|
||||
Assert.assertTrue(result.contains("OK"));
|
||||
}
|
||||
}
|
||||
195
test/javax/servlet/jsp/TesterPageContext.java
Normal file
195
test/javax/servlet/jsp/TesterPageContext.java
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* 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 javax.servlet.jsp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
public class TesterPageContext extends PageContext {
|
||||
|
||||
@Override
|
||||
public void initialize(Servlet servlet, ServletRequest request,
|
||||
ServletResponse response, String errorPageURL,
|
||||
boolean needsSession, int bufferSize, boolean autoFlush)
|
||||
throws IOException, IllegalStateException, IllegalArgumentException {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpSession getSession() {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPage() {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletRequest getRequest() {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletResponse getResponse() {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Exception getException() {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletConfig getServletConfig() {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forward(String relativeUrlPath) throws ServletException,
|
||||
IOException {
|
||||
// NO-OP
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void include(String relativeUrlPath) throws ServletException,
|
||||
IOException {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void include(String relativeUrlPath, boolean flush)
|
||||
throws ServletException, IOException {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePageException(Exception e) throws ServletException,
|
||||
IOException {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePageException(Throwable t) throws ServletException,
|
||||
IOException {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, Object value) {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, Object value, int scope) {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name) {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name, int scope) {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object findAttribute(String name) {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String name) {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String name, int scope) {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttributesScope(String name) {
|
||||
// NO-OP
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<String> getAttributeNamesInScope(int scope) {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JspWriter getOut() {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public javax.servlet.jsp.el.ExpressionEvaluator getExpressionEvaluator() {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ELContext getELContext() {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public javax.servlet.jsp.el.VariableResolver getVariableResolver() {
|
||||
// NO-OP
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
39
test/javax/servlet/jsp/el/TestScopedAttributeELResolver.java
Normal file
39
test/javax/servlet/jsp/el/TestScopedAttributeELResolver.java
Normal 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 javax.servlet.jsp.el;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.startup.TomcatBaseTest;
|
||||
import org.apache.tomcat.util.buf.ByteChunk;
|
||||
|
||||
public class TestScopedAttributeELResolver extends TomcatBaseTest {
|
||||
|
||||
@Test
|
||||
public void testBug49196() throws Exception {
|
||||
getTomcatInstanceTestWebapp(true, true);
|
||||
|
||||
ByteChunk res = getUrl("http://localhost:" + getPort() +
|
||||
"/test/bug6nnnn/bug62453.jsp");
|
||||
|
||||
String result = res.toString();
|
||||
Assert.assertTrue(result, result.contains("<div>foo: OK</div>"));
|
||||
Assert.assertTrue(result, result.contains("<div>bar: </div>"));
|
||||
Assert.assertTrue(result, result.contains("<div>baz: </div>"));
|
||||
}
|
||||
}
|
||||
@@ -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 javax.servlet.jsp.el;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELManager;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.StandardELContext;
|
||||
import javax.servlet.jsp.JspContext;
|
||||
import javax.servlet.jsp.TesterPageContext;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestScopedAttributeELResolverPerformance {
|
||||
|
||||
/*
|
||||
* With the caching of NotFound responses this test takes ~20ms. Without the
|
||||
* caching it takes ~6s.
|
||||
*/
|
||||
@Test
|
||||
public void testGetValuePerformance() throws Exception {
|
||||
|
||||
ELContext context = new StandardELContext(ELManager.getExpressionFactory());
|
||||
|
||||
context.putContext(JspContext.class, new TesterPageContext());
|
||||
|
||||
ELResolver resolver = new ScopedAttributeELResolver();
|
||||
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
resolver.getValue(context, null, "unknown");
|
||||
}
|
||||
}
|
||||
}
|
||||
132
test/javax/servlet/resources/TestSchemaValidation.java
Normal file
132
test/javax/servlet/resources/TestSchemaValidation.java
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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 javax.servlet.resources;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.tomcat.util.descriptor.DigesterFactory;
|
||||
import org.apache.tomcat.util.descriptor.XmlErrorHandler;
|
||||
import org.apache.tomcat.util.descriptor.XmlIdentifiers;
|
||||
import org.apache.tomcat.util.descriptor.web.WebRuleSet;
|
||||
import org.apache.tomcat.util.descriptor.web.WebXml;
|
||||
import org.apache.tomcat.util.digester.Digester;
|
||||
|
||||
public class TestSchemaValidation {
|
||||
|
||||
@Test
|
||||
public void testWebapp() throws Exception {
|
||||
XmlErrorHandler handler = new XmlErrorHandler();
|
||||
Digester digester = DigesterFactory.newDigester(
|
||||
true, true, new WebRuleSet(false), true);
|
||||
digester.setErrorHandler(handler);
|
||||
digester.push(new WebXml());
|
||||
WebXml desc = (WebXml) digester.parse(
|
||||
new File("test/webapp/WEB-INF/web.xml"));
|
||||
Assert.assertEquals("3.1", desc.getVersion());
|
||||
Assert.assertEquals(0, handler.getErrors().size());
|
||||
Assert.assertEquals(0, handler.getWarnings().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebapp_2_2() throws Exception {
|
||||
XmlErrorHandler handler = new XmlErrorHandler();
|
||||
Digester digester = DigesterFactory.newDigester(
|
||||
true, true, new WebRuleSet(false), true);
|
||||
digester.setErrorHandler(handler);
|
||||
digester.push(new WebXml());
|
||||
WebXml desc = (WebXml) digester.parse(
|
||||
new File("test/webapp-2.2/WEB-INF/web.xml"));
|
||||
Assert.assertEquals("2.2", desc.getVersion());
|
||||
Assert.assertEquals(XmlIdentifiers.WEB_22_PUBLIC, desc.getPublicId());
|
||||
Assert.assertEquals(0, handler.getErrors().size());
|
||||
Assert.assertEquals(0, handler.getWarnings().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebapp_2_3() throws Exception {
|
||||
XmlErrorHandler handler = new XmlErrorHandler();
|
||||
Digester digester = DigesterFactory.newDigester(
|
||||
true, true, new WebRuleSet(false), true);
|
||||
digester.setErrorHandler(handler);
|
||||
digester.push(new WebXml());
|
||||
WebXml desc = (WebXml) digester.parse(
|
||||
new File("test/webapp-2.3/WEB-INF/web.xml"));
|
||||
Assert.assertEquals("2.3", desc.getVersion());
|
||||
Assert.assertEquals(XmlIdentifiers.WEB_23_PUBLIC, desc.getPublicId());
|
||||
Assert.assertEquals(0, handler.getErrors().size());
|
||||
Assert.assertEquals(0, handler.getWarnings().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebapp_2_4() throws Exception {
|
||||
XmlErrorHandler handler = new XmlErrorHandler();
|
||||
Digester digester = DigesterFactory.newDigester(
|
||||
true, true, new WebRuleSet(false), true);
|
||||
digester.setErrorHandler(handler);
|
||||
digester.push(new WebXml());
|
||||
WebXml desc = (WebXml) digester.parse(
|
||||
new File("test/webapp-2.4/WEB-INF/web.xml"));
|
||||
Assert.assertEquals("2.4", desc.getVersion());
|
||||
Assert.assertEquals(0, handler.getErrors().size());
|
||||
Assert.assertEquals(0, handler.getWarnings().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebapp_2_5() throws Exception {
|
||||
XmlErrorHandler handler = new XmlErrorHandler();
|
||||
Digester digester = DigesterFactory.newDigester(
|
||||
true, true, new WebRuleSet(false), true);
|
||||
digester.setErrorHandler(handler);
|
||||
digester.push(new WebXml());
|
||||
WebXml desc = (WebXml) digester.parse(
|
||||
new File("test/webapp-2.5/WEB-INF/web.xml"));
|
||||
Assert.assertEquals("2.5", desc.getVersion());
|
||||
Assert.assertEquals(0, handler.getErrors().size());
|
||||
Assert.assertEquals(0, handler.getWarnings().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebapp_3_0() throws Exception {
|
||||
XmlErrorHandler handler = new XmlErrorHandler();
|
||||
Digester digester = DigesterFactory.newDigester(
|
||||
true, true, new WebRuleSet(false), true);
|
||||
digester.setErrorHandler(handler);
|
||||
digester.push(new WebXml());
|
||||
WebXml desc = (WebXml) digester.parse(
|
||||
new File("test/webapp-3.0/WEB-INF/web.xml"));
|
||||
Assert.assertEquals("3.0", desc.getVersion());
|
||||
Assert.assertEquals(0, handler.getErrors().size());
|
||||
Assert.assertEquals(0, handler.getWarnings().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebapp_3_1() throws Exception {
|
||||
XmlErrorHandler handler = new XmlErrorHandler();
|
||||
Digester digester = DigesterFactory.newDigester(
|
||||
true, true, new WebRuleSet(false), true);
|
||||
digester.setErrorHandler(handler);
|
||||
digester.push(new WebXml());
|
||||
WebXml desc = (WebXml) digester.parse(
|
||||
new File("test/webapp-3.1/WEB-INF/web.xml"));
|
||||
Assert.assertEquals("3.1", desc.getVersion());
|
||||
Assert.assertEquals(0, handler.getErrors().size());
|
||||
Assert.assertEquals(0, handler.getWarnings().size());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user