From 09a32e5c49cb4c86b039ee52299bf9fec8a7ed5a Mon Sep 17 00:00:00 2001 From: baranowb Date: Fri, 24 Jan 2025 14:32:57 +0100 Subject: [PATCH] [UNDERTOW-2536] Fix include parameters on error and add rudimentary test --- .../servlet/spec/RequestDispatcherImpl.java | 7 + .../AttributeComparisonTestBase.java | 51 ++++++ ...DispatcherErrorForwardServletTestCase.java | 165 ++++++++++++++++++ ...DispatcherErrorIncludeServletTestCase.java | 164 +++++++++++++++++ .../attributes/ErrorHandlingServlet.java | 71 ++++++++ .../attributes/ErrorSpewServlet.java | 45 +++++ .../dispatcher/attributes/ForwardServlet.java | 55 ++++++ .../dispatcher/attributes/IncludeServlet.java | 56 ++++++ 8 files changed, 614 insertions(+) create mode 100644 servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/AttributeComparisonTestBase.java create mode 100644 servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/DispatcherErrorForwardServletTestCase.java create mode 100644 servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/DispatcherErrorIncludeServletTestCase.java create mode 100644 servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ErrorHandlingServlet.java create mode 100644 servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ErrorSpewServlet.java create mode 100644 servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ForwardServlet.java create mode 100644 servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/IncludeServlet.java diff --git a/servlet/src/main/java/io/undertow/servlet/spec/RequestDispatcherImpl.java b/servlet/src/main/java/io/undertow/servlet/spec/RequestDispatcherImpl.java index 4ed9e9b455..6265085603 100644 --- a/servlet/src/main/java/io/undertow/servlet/spec/RequestDispatcherImpl.java +++ b/servlet/src/main/java/io/undertow/servlet/spec/RequestDispatcherImpl.java @@ -401,6 +401,13 @@ private void error(ServletRequestContext servletRequestContext, final ServletReq final ServletRequest oldRequest = servletRequestContext.getServletRequest(); final ServletResponse oldResponse = servletRequestContext.getServletResponse(); + request.removeAttribute(INCLUDE_REQUEST_URI); + request.removeAttribute(INCLUDE_CONTEXT_PATH); + request.removeAttribute(INCLUDE_SERVLET_PATH); + request.removeAttribute(INCLUDE_PATH_INFO); + request.removeAttribute(INCLUDE_QUERY_STRING); + request.removeAttribute(INCLUDE_MAPPING); + ServletPathMatch pathMatch; try { pathMatch = DispatchUtils.dispatchError(path, servletName, exception, message, requestImpl, responseImpl, servletContext); diff --git a/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/AttributeComparisonTestBase.java b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/AttributeComparisonTestBase.java new file mode 100644 index 0000000000..af0116aae1 --- /dev/null +++ b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/AttributeComparisonTestBase.java @@ -0,0 +1,51 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2025 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed 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 io.undertow.servlet.test.dispatcher.attributes; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Map; +import java.util.TreeMap; + +public abstract class AttributeComparisonTestBase { + + protected void testAttributes(final Map expected, final String incoming) throws RuntimeException { + + final Map incomingParameters = new TreeMap(); + final Map expectedParameters = new TreeMap(); + expectedParameters.putAll(expected); + System.err.println("INCOMING: "+incoming); + final String[] array = incoming.split("\n"); + System.err.println("INCOMING: "+Arrays.toString(array)); + for (String kvp : array) { + // this might not be best way, but... + final String[] split = kvp.split(";"); + final String splitValue = split.length == 2 ? split[1] : ""; //thats empty string. + // sanity check + final String errorIfNotNull = incomingParameters.put(split[0], splitValue); + // should not happen? + assertNull("Doubled value of key[" + split[0] + "] = [" + errorIfNotNull + "," + splitValue + "]", errorIfNotNull); + assertTrue("Expected parameters does not contain '" + split[0] + "'", expectedParameters.containsKey(split[0])); + assertEquals(expectedParameters.remove(split[0]), splitValue); + } + assertTrue("Too many expected parameters: " + expectedParameters, expectedParameters.size() == 0); + } +} diff --git a/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/DispatcherErrorForwardServletTestCase.java b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/DispatcherErrorForwardServletTestCase.java new file mode 100644 index 0000000000..fdde7cabb0 --- /dev/null +++ b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/DispatcherErrorForwardServletTestCase.java @@ -0,0 +1,165 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2025 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed 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 io.undertow.servlet.test.dispatcher.attributes; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.junit.Assume; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import io.undertow.server.handlers.PathHandler; +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.DeploymentManager; +import io.undertow.servlet.api.ErrorPage; +import io.undertow.servlet.api.ServletContainer; +import io.undertow.servlet.api.ServletInfo; +import io.undertow.servlet.test.SimpleServletTestCase; +import io.undertow.servlet.test.util.TestClassIntrospector; +import io.undertow.servlet.test.util.TestResourceLoader; +import io.undertow.testutils.DefaultServer; +import io.undertow.testutils.HttpClientUtils; +import io.undertow.testutils.ProxyIgnore; +import io.undertow.testutils.TestHttpClient; +import io.undertow.util.StatusCodes; +import jakarta.servlet.ServletException; + +/** + * @author baranowb + */ +@RunWith(DefaultServer.class) +@ProxyIgnore +public class DispatcherErrorForwardServletTestCase extends AttributeComparisonTestBase { + + static final String TARGET = ""; + @BeforeClass + public static void setup() throws ServletException { + //we don't run this test on h2 upgrade, as if it is run with the original request + //the protocols will not match + Assume.assumeFalse(DefaultServer.isH2upgrade()); + final PathHandler root = new PathHandler(); + final ServletContainer container = ServletContainer.Factory.newInstance(); + + DeploymentInfo builder = new DeploymentInfo() + //no idea why... + .setClassLoader(SimpleServletTestCase.class.getClassLoader()) + .setContextPath("/servletContext") + .setClassIntrospecter(TestClassIntrospector.INSTANCE) + .setDeploymentName("servletContext.war") + .setResourceManager(new TestResourceLoader(DispatcherErrorForwardServletTestCase.class)) + //test servlet, we need info from it + .addServlet(new ServletInfo("error", ErrorHandlingServlet.class) + .addMapping("/error")) + //return handler, which should send us stuff + .addServlet(new ServletInfo("target", ErrorSpewServlet.class) + .addMapping("/target")) + //fwd + .addServlet(new ServletInfo("fwd", ForwardServlet.class) + .addMapping("/forward")) + //error mapge mapping to servlet + .addErrorPage(new ErrorPage("/error")); + + DeploymentManager manager = container.addDeployment(builder); + manager.deploy(); + root.addPrefixPath(builder.getContextPath(), manager.start()); + DefaultServer.setRootHandler(root); + } + + @Test + public void testSimpleForwardWithError() throws IOException, InterruptedException { + //Expected params: + final Map expectedParams = new TreeMap(); + // jakarta.servlet.async.mapping + // jakarta.servlet.async.request_uri + // jakarta.servlet.async.context_path + // jakarta.servlet.async.servlet_path + // jakarta.servlet.async.path_info + // jakarta.servlet.async.query_string + expectedParams.put("jakarta.servlet.forward.request_uri", "/servletContext/forward"); + expectedParams.put("jakarta.servlet.forward.servlet_path", "/forward"); + expectedParams.put("jakarta.servlet.forward.context_path", "/servletContext"); + expectedParams.put("jakarta.servlet.forward.mapping", + "match_value=forward,pattern=/forward,servlet_name=fwd,mapping_match=EXACT"); + //https://jakarta.ee/specifications/servlet/5.0/jakarta-servlet-spec-5.0#request-attributes + // jakarta.servlet.error.request_uri + // jakarta.servlet.error.servlet_name + // jakarta.servlet.error.exception_type + // jakarta.servlet.error.exception + // jakarta.servlet.error.message + // jakarta.servlet.error.status_code + expectedParams.put("jakarta.servlet.error.request_uri", "/servletContext/forward"); + expectedParams.put("jakarta.servlet.error.servlet_name", "fwd"); + expectedParams.put("jakarta.servlet.error.exception_type", "class jakarta.servlet.ServletException"); + expectedParams.put("jakarta.servlet.error.exception", "jakarta.servlet.ServletException: HEY"); + expectedParams.put("jakarta.servlet.error.message", "HEY"); + expectedParams.put("jakarta.servlet.error.status_code", "500"); + TestHttpClient client = new TestHttpClient(); + try { + HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/servletContext/forward"); + get.setHeader("forward", "/target"); + get.setHeader("throw", "true"); + HttpResponse result = client.execute(get); + assertEquals(StatusCodes.OK, result.getStatusLine().getStatusCode()); + final String response = HttpClientUtils.readResponse(result); + assertNotNull(response); + super.testAttributes(expectedParams, response); + } finally { + client.getConnectionManager().shutdown(); + } + } + + @Test + public void testSimpleForwardWithNoError() throws IOException, InterruptedException { + //Expected params: + //https://jakarta.ee/specifications/servlet/5.0/jakarta-servlet-spec-5.0#forwarded-request-parameters + //Some are missing, since null == omission. + // jakarta.servlet.forward.mapping + // jakarta.servlet.forward.request_uri + // jakarta.servlet.forward.context_path + // jakarta.servlet.forward.servlet_path + // jakarta.servlet.forward.path_info + // jakarta.servlet.forward.query_string + final Map expectedParams = new TreeMap(); + expectedParams.put("jakarta.servlet.forward.request_uri", "/servletContext/forward"); + expectedParams.put("jakarta.servlet.forward.servlet_path", "/forward"); + expectedParams.put("jakarta.servlet.forward.mapping", + "match_value=forward,pattern=/forward,servlet_name=fwd,mapping_match=EXACT"); + expectedParams.put("jakarta.servlet.forward.context_path", "/servletContext"); + TestHttpClient client = new TestHttpClient(); + try { + HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/servletContext/forward"); + get.setHeader("forward", "/target"); + HttpResponse result = client.execute(get); + assertEquals(StatusCodes.OK, result.getStatusLine().getStatusCode()); + final String response = HttpClientUtils.readResponse(result); + assertNotNull(response); + super.testAttributes(expectedParams, response); + } finally { + client.getConnectionManager().shutdown(); + } + } +} diff --git a/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/DispatcherErrorIncludeServletTestCase.java b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/DispatcherErrorIncludeServletTestCase.java new file mode 100644 index 0000000000..c68eb889d6 --- /dev/null +++ b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/DispatcherErrorIncludeServletTestCase.java @@ -0,0 +1,164 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2025 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed 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 io.undertow.servlet.test.dispatcher.attributes; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.junit.Assume; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import io.undertow.server.handlers.PathHandler; +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.DeploymentManager; +import io.undertow.servlet.api.ErrorPage; +import io.undertow.servlet.api.ServletContainer; +import io.undertow.servlet.api.ServletInfo; +import io.undertow.servlet.test.SimpleServletTestCase; +import io.undertow.servlet.test.util.TestClassIntrospector; +import io.undertow.servlet.test.util.TestResourceLoader; +import io.undertow.testutils.DefaultServer; +import io.undertow.testutils.HttpClientUtils; +import io.undertow.testutils.ProxyIgnore; +import io.undertow.testutils.TestHttpClient; +import io.undertow.util.StatusCodes; +import jakarta.servlet.ServletException; + +/** + * @author baranowb + */ +@RunWith(DefaultServer.class) +@ProxyIgnore +public class DispatcherErrorIncludeServletTestCase extends AttributeComparisonTestBase { + + static final String TARGET = "/target"; + @BeforeClass + public static void setup() throws ServletException { + //we don't run this test on h2 upgrade, as if it is run with the original request + //the protocols will not match + Assume.assumeFalse(DefaultServer.isH2upgrade()); + final PathHandler root = new PathHandler(); + final ServletContainer container = ServletContainer.Factory.newInstance(); + + DeploymentInfo builder = new DeploymentInfo() + //no idea why... + .setClassLoader(SimpleServletTestCase.class.getClassLoader()) + .setContextPath("/servletContext") + .setClassIntrospecter(TestClassIntrospector.INSTANCE) + .setDeploymentName("servletContext.war") + .setResourceManager(new TestResourceLoader(DispatcherErrorIncludeServletTestCase.class)) + //test servlet, we need info from it + .addServlet(new ServletInfo("error", ErrorHandlingServlet.class) + .addMapping("/error")) + //return handler, which should send us stuff + .addServlet(new ServletInfo("target", ErrorSpewServlet.class) + .addMapping(TARGET)) + //fwd + .addServlet(new ServletInfo("inc", IncludeServlet.class) + .addMapping("/include")) + //error mapge mapping to servlet + .addErrorPage(new ErrorPage("/error")); + + DeploymentManager manager = container.addDeployment(builder); + manager.deploy(); + root.addPrefixPath(builder.getContextPath(), manager.start()); + DefaultServer.setRootHandler(root); + } + + @Test + public void testSimpleIncludeWithError() throws IOException, InterruptedException { + final Map expectedParams = new TreeMap(); + // jakarta.servlet.async.mapping + // jakarta.servlet.async.request_uri + // jakarta.servlet.async.context_path + // jakarta.servlet.async.servlet_path + // jakarta.servlet.async.path_info + // jakarta.servlet.async.query_string + + expectedParams.put("jakarta.servlet.forward.request_uri", "/servletContext/include"); + expectedParams.put("jakarta.servlet.forward.servlet_path", "/include"); + expectedParams.put("jakarta.servlet.error.servlet_name", "inc"); + expectedParams.put("jakarta.servlet.forward.mapping", + "match_value=include,pattern=/include,servlet_name=inc,mapping_match=EXACT"); + expectedParams.put("jakarta.servlet.forward.context_path", "/servletContext"); + //https://jakarta.ee/specifications/servlet/5.0/jakarta-servlet-spec-5.0#request-attributes + // jakarta.servlet.error.request_uri + // jakarta.servlet.error.servlet_name + // jakarta.servlet.error.exception_type + // jakarta.servlet.error.exception + // jakarta.servlet.error.message + // jakarta.servlet.error.status_code + expectedParams.put("jakarta.servlet.error.request_uri", "/servletContext/include"); + expectedParams.put("jakarta.servlet.error.exception_type", "class jakarta.servlet.ServletException"); + expectedParams.put("jakarta.servlet.error.exception", "jakarta.servlet.ServletException: HEY"); + expectedParams.put("jakarta.servlet.error.message", "HEY"); + expectedParams.put("jakarta.servlet.error.status_code", "500"); + TestHttpClient client = new TestHttpClient(); + try { + HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/servletContext/include"); + get.setHeader("include", TARGET); + get.setHeader("throw", "true"); + HttpResponse result = client.execute(get); + assertEquals(StatusCodes.OK, result.getStatusLine().getStatusCode()); + final String response = HttpClientUtils.readResponse(result); + assertNotNull(response); + super.testAttributes(expectedParams, response); + } finally { + client.getConnectionManager().shutdown(); + } + } + + @Test + public void testSimpleIncludeWithNoError() throws IOException, InterruptedException { + //https://jakarta.ee/specifications/servlet/5.0/jakarta-servlet-spec-5.0#included-request-parameters + // jakarta.servlet.include.request_uri + // jakarta.servlet.include.context_path + // jakarta.servlet.include.query_string + // jakarta.servlet.include.servlet_path + // jakarta.servlet.include.mapping + // jakarta.servlet.include.path_info + final Map expectedParams = new TreeMap(); + expectedParams.put("jakarta.servlet.include.request_uri", "/servletContext/target"); + expectedParams.put("jakarta.servlet.include.context_path", "/servletContext"); + expectedParams.put("jakarta.servlet.include.query_string", ""); + expectedParams.put("jakarta.servlet.include.servlet_path", TARGET); + expectedParams.put("jakarta.servlet.include.mapping", + "match_value=include,pattern=/include,servlet_name=inc,mapping_match=EXACT"); + TestHttpClient client = new TestHttpClient(); + try { + HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/servletContext/include"); + get.setHeader("include", TARGET); + HttpResponse result = client.execute(get); + assertEquals(StatusCodes.OK, result.getStatusLine().getStatusCode()); + final String response = HttpClientUtils.readResponse(result); + assertNotNull(response); + super.testAttributes(expectedParams, response); + } finally { + client.getConnectionManager().shutdown(); + } + } +} diff --git a/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ErrorHandlingServlet.java b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ErrorHandlingServlet.java new file mode 100644 index 0000000000..6c6103ead4 --- /dev/null +++ b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ErrorHandlingServlet.java @@ -0,0 +1,71 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2025 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed 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 io.undertow.servlet.test.dispatcher.attributes; + +import java.io.IOException; +import java.util.Enumeration; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletMapping; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * @author baranowb + */ +public class ErrorHandlingServlet extends HttpServlet { + + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { + //test if on error we get proper set of attribs, regardless of downstream stuff. + final Enumeration attribs = req.getAttributeNames(); + final StringBuilder responseBuilder = new StringBuilder(); + while(attribs.hasMoreElements()) { + final String key = attribs.nextElement(); + final Object value = req.getAttribute(key); + responseBuilder.append(key); + responseBuilder.append(";"); + if(value instanceof HttpServletMapping) { + final HttpServletMapping hsm = (HttpServletMapping) value; + responseBuilder.append("match_value").append("=").append(hsm.getMatchValue()).append(","); + responseBuilder.append("pattern").append("=").append(hsm.getPattern()).append(","); + responseBuilder.append("servlet_name").append("=").append(hsm.getServletName()).append(","); + responseBuilder.append("mapping_match").append("=").append(hsm.getMappingMatch()); + } else { + responseBuilder.append(value); + } + responseBuilder.append("\n"); + } + final Enumeration parameters = req.getParameterNames(); + + while(parameters.hasMoreElements()) { + final String key = parameters.nextElement(); + final String value = req.getParameter(key); + responseBuilder.append(key); + responseBuilder.append(":"); + responseBuilder.append(value); + responseBuilder.append("\n"); + } + resp.getOutputStream().write(responseBuilder.toString().getBytes()); + resp.setStatus(200); + resp.flushBuffer(); + } + +} diff --git a/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ErrorSpewServlet.java b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ErrorSpewServlet.java new file mode 100644 index 0000000000..8efe197cdc --- /dev/null +++ b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ErrorSpewServlet.java @@ -0,0 +1,45 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2025 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed 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 io.undertow.servlet.test.dispatcher.attributes; + +import java.io.IOException; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * Simple... just throw something + * @author baranowb + */ +public class ErrorSpewServlet extends ErrorHandlingServlet { + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { + if (req.getHeader("throw") != null) { + throw new ServletException("HEY"); + } else { + //just report content + super.doGet(req, resp); + } + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doGet(req, resp); + } +} diff --git a/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ForwardServlet.java b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ForwardServlet.java new file mode 100644 index 0000000000..3602e20312 --- /dev/null +++ b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/ForwardServlet.java @@ -0,0 +1,55 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2025 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed 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 io.undertow.servlet.test.dispatcher.attributes; + +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Stuart Douglas + */ +public class ForwardServlet extends HttpServlet { + + public static final String MESSAGE = "Hello "; + + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { + RequestDispatcher dispatcher; + if (req.getHeader("name") != null) { + dispatcher = req.getServletContext().getNamedDispatcher(req.getHeader("forward")); + } else { + dispatcher = req.getRequestDispatcher(req.getHeader("forward")); + } + if (dispatcher != null) { + dispatcher.forward(req, resp); + } else { + resp.sendError(500, "dispatcher was null!"); + } + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doGet(req, resp); + } + +} diff --git a/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/IncludeServlet.java b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/IncludeServlet.java new file mode 100644 index 0000000000..548f4d3bd9 --- /dev/null +++ b/servlet/src/test/java/io/undertow/servlet/test/dispatcher/attributes/IncludeServlet.java @@ -0,0 +1,56 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2025 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed 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 io.undertow.servlet.test.dispatcher.attributes; + +import java.io.IOException; + +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * @author Stuart Douglas + */ +public class IncludeServlet extends HttpServlet { + + public static final String MESSAGE = "Hello "; + + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { + RequestDispatcher dispatcher; + if (req.getHeader("name") != null) { + dispatcher = req.getServletContext().getNamedDispatcher(req.getHeader("include")); + } else { + String include = req.getParameter("include"); + if (include == null) { + include = req.getHeader("include"); + } + dispatcher = req.getRequestDispatcher(include); + } + dispatcher.include(req, resp); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doGet(req, resp); + } + +}