diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java index d9ad0741a655..6ff57819d985 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java @@ -397,7 +397,7 @@ protected void writeErrorPageBody(HttpServletRequest request, Writer writer, int writeErrorPageStacks(request, writer); Request.getBaseRequest(request).getHttpChannel().getHttpConfiguration() - .writePoweredBy(writer, "
", "
\n"); + .writePoweredBy(writer, "
", "
\n"); } protected void writeErrorPageMessage(HttpServletRequest request, Writer writer, int code, String message, String uri) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java index 1860d234995e..27b8b6d367f5 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java @@ -18,7 +18,9 @@ package org.eclipse.jetty.server; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -27,6 +29,9 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpHeader; @@ -43,6 +48,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.w3c.dom.Document; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.anyOf; @@ -567,7 +573,7 @@ public void testComplexCauseMessageAcceptUtf8Header(String path) throws Exceptio } } - private String assertContent(HttpTester.Response response) + private String assertContent(HttpTester.Response response) throws Exception { String contentType = response.get(HttpHeader.CONTENT_TYPE); String content = response.getContent(); @@ -578,6 +584,17 @@ private String assertContent(HttpTester.Response response) assertThat(content, not(containsString(""))); assertThat(content, not(containsString(""))); assertThat(content, not(containsString("€"))); + + // we expect that our generated output conforms to text/xhtml is well formed + DocumentBuilderFactory xmlDocumentBuilderFactory = DocumentBuilderFactory.newInstance(); + xmlDocumentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + DocumentBuilder db = xmlDocumentBuilderFactory.newDocumentBuilder(); + try (ByteArrayInputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))) + { + // We consider this content to be XML well formed if these 2 lines do not throw an Exception + Document doc = db.parse(inputStream); + doc.getDocumentElement().normalize(); + } } else if (contentType.contains("text/json")) {