diff --git a/api/src/main/resources/jakarta/servlet/resources/web-common_6_2.xsd b/api/src/main/resources/jakarta/servlet/resources/web-common_6_2.xsd index 7234a9c74f..4e5896e399 100644 --- a/api/src/main/resources/jakarta/servlet/resources/web-common_6_2.xsd +++ b/api/src/main/resources/jakarta/servlet/resources/web-common_6_2.xsd @@ -9,7 +9,8 @@ - Copyright (c) 2009, 2024 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2009, 2025 Oracle and/or its affiliates and others. + All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v. 2.0, which is available at @@ -1337,9 +1338,11 @@ - The welcome-file element contains a file name to use - as a default welcome file, such as index.html - + The welcome-file element contains a file name to use as a + welcome file, such as index.html, that must match an + actual file or be an exact or prefix match to a servlet + URL pattern. + @@ -1348,9 +1351,10 @@ - The welcome-servlet element contains servlet name to use - as a default welcome servlet, such as index.do - + The welcome-servlet element contains a file name to use as + a welcome file, such as index.do, that must match a + servlet mapping other than that for the default servlet. + diff --git a/spec/src/main/asciidoc/servlet-spec-body.adoc b/spec/src/main/asciidoc/servlet-spec-body.adoc index 85eb3f7ded..58c36624b1 100644 --- a/spec/src/main/asciidoc/servlet-spec-body.adoc +++ b/spec/src/main/asciidoc/servlet-spec-body.adoc @@ -3726,9 +3726,15 @@ In addition to these annotations all the annotations defined in <> will continue to work in the context of these new annotations. -By default all applications will have -`index.htm[l]` and `index.jsp` in the `welcome-file-list`. The -descriptor may to be used to override these default settings. +By default all applications will have a `welcome-file-list` of: +``` + + index.html + index.htm + index.jsp + +``` +The descriptor may to be used to override these default settings. The order in which the listeners, servlets are loaded from the various framework jars / classes in the @@ -4323,7 +4329,7 @@ but with different `` elements, and the same servlet is also declared in the main `web.xml`, but without any ``, then an error must be reported. -... `` declarations are additive. +... `` and `` declarations are additive. ... `` elements with the same `` are additive across `web-fragments`. @@ -5442,7 +5448,7 @@ the following types of configuration and deployment information: * MIME Type Mappings -* Welcome File list +* Welcome Resources List * Error Pages @@ -5653,10 +5659,10 @@ the container. The mechanism described in may be used to specify filters that are applied before an error response is generated. -=== Welcome Files +=== Welcome Resources Application Developers can define an -ordered list of partial URIs called welcome files in the web application +ordered list of partial URIs called welcome resources in the web application deployment descriptor. The deployment descriptor syntax for the list is described in the web application deployment descriptor schema. @@ -5673,26 +5679,40 @@ where `directory` is an entry in the WAR that is not mapped to a servlet or JSP page, is returned to the client as `host:port/webapp/directory/index.html`. -If a web container receives a valid partial -request, the web container must examine the welcome file list defined in -the deployment descriptor. The welcome file list is an ordered list of -partial URLs with no trailing or leading `"/"`. The web server must append -each welcome file in the order specified in the deployment descriptor to -the partial request and check whether a static resource in the WAR is -mapped to that request URI. If no match is found, the web server MUST -again append each welcome file in the order specified in the deployment -descriptor to the partial request and check if a servlet is mapped to -that request URI. The web container must send the request to the first -resource in the WAR that matches. - -If a matching welcome file is found in the manner described, the container may +Deployment descriptors that declare a version of 6.2 or later, may define +welcome files or welcome servlets. Deployment descriptors that declare an +earlier version than 6.2 define legacy welcome files. + +The web container identifies the servlet to serve the request using the process +described in the following paragraphs. The process stops when the first match is +found. + +For each welcome resource in the order it appears in the deployment descriptor: +- append the partial URI to the request URI to create a welcome URI +- if the welcome URI has an exact match to a servlet mapping, send the request + to that servlet +- if the welcome URI has a prefix match to a servlet mapping, send the request + to that servlet +- if the welcome resource is a welcome file or legacy welcome file and a static + file exists in the web application for the welcome URI, send the request to + that static resource +- if the welcome resource is a welcome servlet and a servlet mapping (other than + the default servlet) matches the welcome URI, send the request to that servlet + +If no match is found then for each legacy welcome file in the order they appear +in the deployment descriptor: +- append the partial URI to the request URI to create a welcome URI +- if a servlet mapping (other than the default servlet) matches the welcome URI, + send the request to that servlet + +If a matching welcome resource is found in the manner described, the container may send the request to the welcome resource with a forward, a redirect, or a container specific mechanism that is indistinguishable from a direct request. In later case, the request information (e.g. `getRequestURI()`) presented to the filter chain and the servlet will include the welcome file since filter mapping occurs after welcome file mapping. -If no matching welcome file is found in the +If no matching welcome resource is found in the manner described, the container may handle the request in a manner it finds suitable. For some configurations this may mean returning a directory listing or for others returning a `404` response. @@ -8560,6 +8580,14 @@ can be mapped to a physical path but the physical path does not exist. link:https://github.com/jakartaee/servlet/issues/18[Issue 18]:: Clarify the behaviour of `HttpServletRequest.getContextPath()`. +link:https://github.com/jakartaee/servlet/issues/20[Issue 20]:: +Introduce a new element, `` to the web.xml schema that can be +used to specify a welcome resource that is not backed by a file but is backed by +a servlet. With the introduction of this new element, the rules for mapping +welcome resources have been updated to differentiate welcome resources that are +expected to be backed by files and those that are only expected to be backed by +a servlet. + link:https://github.com/jakartaee/servlet/issues/25[Issue 25]:: Document the risks created by a filter modifying the `ServletResponse`. Add a recommendation that filters that modify the `ServletResponse` should endeavour diff --git a/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/IndexServletDo.java b/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/IndexServletDo.java new file mode 100644 index 0000000000..5e299df5f1 --- /dev/null +++ b/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/IndexServletDo.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package servlet.tck.spec.welcomefiles; + +import java.io.IOException; +import java.io.PrintWriter; + +import jakarta.servlet.GenericServlet; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; + +/** + * Simple servlet used for the welcome servlet tests. + */ +public class IndexServletDo extends GenericServlet { + + private static final long serialVersionUID = 1L; + + @Override + public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { + PrintWriter pw = response.getWriter(); + // Test looks for this string to confirm the welcome servlet was used. + pw.println("INDEX from *.do"); + } +} diff --git a/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/WelcomeFilesFileTests.java b/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/WelcomeFilesFileTests.java new file mode 100644 index 0000000000..43686c5851 --- /dev/null +++ b/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/WelcomeFilesFileTests.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package servlet.tck.spec.welcomefiles; + +import servlet.tck.common.client.AbstractTckTest; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +public class WelcomeFilesFileTests extends AbstractTckTest { + + /** + * Deployment for the test. + * + * @return The web archive to test. + * + * @throws Exception If an error occurs creating the archive. + */ + @Deployment(testable = false) + public static WebArchive getTestArchive() throws Exception { + WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "servlet_spec_welcomefiles_file_web.war") + .addClasses(IndexServletDo.class) + .setWebXML(WelcomeFilesFileTests.class.getResource("servlet_spec_welcomefiles_file_web.xml")); + Arrays.asList("legacy/index.html") + .forEach(s -> webArchive.addAsWebResource("spec/welcomefiles/" +s, s)); + return webArchive; + } + + + /* + * Test should trigger a 404 since index.do is configured as a welcome file and no such file exists. + */ + @Test + public void partialfoundLegacy() throws Exception { + TEST_PROPS.get().setProperty(FOLLOW_REDIRECT, "follow_redirect"); + TEST_PROPS.get().setProperty(STATUS_CODE, NOT_FOUND); + TEST_PROPS.get().setProperty(SEARCH_STRING, " webArchive.addAsWebResource("spec/welcomefiles/" +s, s)); + return webArchive; + } + + + /* + * Test should trigger a 404 since default.jsp is a valid welcome file but does not exist. + */ + @Test + public void partialfoundLegacy() throws Exception { + TEST_PROPS.get().setProperty(FOLLOW_REDIRECT, "follow_redirect"); + TEST_PROPS.get().setProperty(STATUS_CODE, NOT_FOUND); + TEST_PROPS.get().setProperty(SEARCH_STRING, " webArchive.addAsWebResource("spec/welcomefiles/" +s, s)); + return webArchive; + } + + + /* + * Test should use the index.do mapping since it is configured as a welcome-servlet. + */ + @Test + public void partialfoundServlet() throws Exception { + TEST_PROPS.get().setProperty(FOLLOW_REDIRECT, "follow_redirect"); + TEST_PROPS.get().setProperty(SEARCH_STRING, "INDEX from *.do"); + TEST_PROPS.get().setProperty(APITEST, "legacy"); + invoke(); + } +} diff --git a/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/servlet_spec_welcomefiles_file_web.xml b/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/servlet_spec_welcomefiles_file_web.xml new file mode 100644 index 0000000000..373542e9d2 --- /dev/null +++ b/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/servlet_spec_welcomefiles_file_web.xml @@ -0,0 +1,40 @@ + + + + Welcome Files - File + + DefaultLegacyJSP + /legacy/default.jsp + + + IndexDo + servlet.tck.spec.welcomefiles.IndexServletDo + + + IndexDo + *.do + + + default.jsp + index.do + + diff --git a/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/servlet_spec_welcomefiles_legacy_web.xml b/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/servlet_spec_welcomefiles_legacy_web.xml new file mode 100644 index 0000000000..1b64e67161 --- /dev/null +++ b/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/servlet_spec_welcomefiles_legacy_web.xml @@ -0,0 +1,43 @@ + + + + + Welcome Files - Legacy + + DefaultLegacyJSP + /legacy/default.jsp + + + IndexDo + servlet.tck.spec.welcomefiles.IndexServletDo + + + IndexDo + *.do + + + default.jsp + index.do + + diff --git a/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/servlet_spec_welcomefiles_servlet_web.xml b/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/servlet_spec_welcomefiles_servlet_web.xml new file mode 100644 index 0000000000..deab6d9c29 --- /dev/null +++ b/tck/tck-runtime/src/main/java/servlet/tck/spec/welcomefiles/servlet_spec_welcomefiles_servlet_web.xml @@ -0,0 +1,40 @@ + + + + Welcome Files - Servlet + + DefaultLegacyJSP + /legacy/default.jsp + + + IndexDo + servlet.tck.spec.welcomefiles.IndexServletDo + + + IndexDo + *.do + + + default.jsp + index.do + + diff --git a/tck/tck-util/src/main/resources/spec/welcomefiles/legacy/index.html b/tck/tck-util/src/main/resources/spec/welcomefiles/legacy/index.html new file mode 100644 index 0000000000..6ee9fffc38 --- /dev/null +++ b/tck/tck-util/src/main/resources/spec/welcomefiles/legacy/index.html @@ -0,0 +1,27 @@ + + + + + index.html + + + INDEX from legacy/index.html + +