You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by jo...@apache.org on 2026/09/16 08:38:35 UTC
(sling-org-apache-sling-engine) 01/01: SLING-13351 make content-type handling consistent
This is an automated email from the ASF dual-hosted git repository.
joerghoh pushed a commit to branch SLING-13351
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-engine.git
commit 50d2118b8de151960bd44ec1ace0aee32ff7b17d
Author: Joerg Hoh <jo...@apache.org>
AuthorDate: Wed Sep 16 10:37:02 2026 +0200
SLING-13351 make content-type handling consistent
the content-type can be set also via setHeader/addHeader, so in these cases the logic of
setContenType should be applied.
---
.../impl/SlingJakartaHttpServletResponseImpl.java | 14 ++++++
.../impl/SlingHttpServletResponseImplTest.java | 57 ++++++++++++++++++++++
2 files changed, 71 insertions(+)
diff --git a/src/main/java/org/apache/sling/engine/impl/SlingJakartaHttpServletResponseImpl.java b/src/main/java/org/apache/sling/engine/impl/SlingJakartaHttpServletResponseImpl.java
index 5ed609b..2a4a19d 100644
--- a/src/main/java/org/apache/sling/engine/impl/SlingJakartaHttpServletResponseImpl.java
+++ b/src/main/java/org/apache/sling/engine/impl/SlingJakartaHttpServletResponseImpl.java
@@ -59,6 +59,8 @@ public class SlingJakartaHttpServletResponseImpl extends HttpServletResponseWrap
private static final String CALL_STACK_MESSAGE = "Call stack causing the content type override violation: ";
+ private static final String HEADER_CONTENT_TYPE = "Content-Type";
+
private static final Logger LOG = LoggerFactory.getLogger(SlingJakartaHttpServletResponseImpl.class);
// this regex matches TIMER_START{ followed by any characters except }, and then
@@ -274,6 +276,12 @@ public class SlingJakartaHttpServletResponseImpl extends HttpServletResponseWrap
@Override
public void addHeader(final String name, final String value) {
+ if (this.isInclude() && HEADER_CONTENT_TYPE.equalsIgnoreCase(name)) {
+ // changing the Content-Type header during an include must be subject
+ // to the same enforcement as setContentType (see setHeader)
+ this.setContentType(value);
+ return;
+ }
if (!this.isProtectHeadersOnInclude()) {
logHeaderModificationCallOnIncludeForMethod("addHeader()");
super.addHeader(name, value);
@@ -307,6 +315,12 @@ public class SlingJakartaHttpServletResponseImpl extends HttpServletResponseWrap
@Override
public void setHeader(final String name, final String value) {
+ if (this.isInclude() && HEADER_CONTENT_TYPE.equalsIgnoreCase(name)) {
+ // changing the Content-Type header during an include must be subject
+ // to the same enforcement as setContentType (see setHeader)
+ this.setContentType(value);
+ return;
+ }
if (!this.isProtectHeadersOnInclude()) {
logHeaderModificationCallOnIncludeForMethod("setHeader()");
super.setHeader(name, value);
diff --git a/src/test/java/org/apache/sling/engine/impl/SlingHttpServletResponseImplTest.java b/src/test/java/org/apache/sling/engine/impl/SlingHttpServletResponseImplTest.java
index fd658f5..b2e84b3 100644
--- a/src/test/java/org/apache/sling/engine/impl/SlingHttpServletResponseImplTest.java
+++ b/src/test/java/org/apache/sling/engine/impl/SlingHttpServletResponseImplTest.java
@@ -374,6 +374,63 @@ public class SlingHttpServletResponseImplTest {
.collect(Collectors.joining(System.lineSeparator())))));
}
+ @Test
+ public void testContentTypeOverrideEnforcedForSetHeader() {
+ final SlingJakartaHttpServletResponse orig = Mockito.mock(SlingJakartaHttpServletResponse.class);
+ final RequestData requestData = mock(RequestData.class);
+ final DispatchingInfo info = new DispatchingInfo(DispatcherType.INCLUDE);
+ final RequestProgressTracker requestProgressTracker = mock(RequestProgressTracker.class);
+ when(requestData.getDispatchingInfo()).thenReturn(info);
+ when(orig.getContentType()).thenReturn("text/plain");
+ when(requestData.getRequestProgressTracker()).thenReturn(requestProgressTracker);
+ ArrayList<String> logMessagesList = new ArrayList<>(Arrays.asList(logMessages));
+ when(requestProgressTracker.getMessages()).thenAnswer(invocation -> logMessagesList.iterator());
+ info.setCheckContentTypeOnInclude(true);
+
+ final SlingRequestProcessorImpl requestProcessor = mock(SlingRequestProcessorImpl.class);
+ when(requestData.getSlingRequestProcessor()).thenReturn(requestProcessor);
+ when(requestData.getActiveServletName()).thenReturn(ACTIVE_SERVLET_NAME);
+
+ final HttpServletResponse include = new SlingJakartaHttpServletResponseImpl(requestData, orig);
+
+ Throwable setHeaderThrowable = null;
+ try {
+ include.setHeader("Content-Type", "text/html");
+ } catch (RuntimeException e) {
+ setHeaderThrowable = e;
+ }
+ assertNotNull("Expected setHeader(\"Content-Type\", ...) to be blocked.", setHeaderThrowable);
+
+ Throwable addHeaderThrowable = null;
+ try {
+ include.addHeader("content-type", "text/html");
+ } catch (RuntimeException e) {
+ addHeaderThrowable = e;
+ }
+ assertNotNull("Expected addHeader(\"content-type\", ...) to be blocked.", addHeaderThrowable);
+
+ Mockito.verify(orig, never()).setHeader(Mockito.anyString(), Mockito.anyString());
+ Mockito.verify(orig, never()).addHeader(Mockito.anyString(), Mockito.anyString());
+ Mockito.verify(orig, never()).setContentType(Mockito.anyString());
+ }
+
+ @Test
+ public void testUnrelatedHeadersNotRoutedThroughContentTypeCheck() {
+ final SlingJakartaHttpServletResponse orig = Mockito.mock(SlingJakartaHttpServletResponse.class);
+ final RequestData requestData = mock(RequestData.class);
+ final DispatchingInfo info = new DispatchingInfo(DispatcherType.INCLUDE);
+ when(requestData.getDispatchingInfo()).thenReturn(info);
+ info.setCheckContentTypeOnInclude(true);
+
+ final HttpServletResponse include = new SlingJakartaHttpServletResponseImpl(requestData, orig);
+
+ include.setHeader("X-Custom", "value");
+ include.addHeader("X-Custom", "another");
+
+ Mockito.verify(orig, times(1)).setHeader("X-Custom", "value");
+ Mockito.verify(orig, times(1)).addHeader("X-Custom", "another");
+ }
+
@Test
public void testContentTypeOverrideDisabled() {
final SlingJakartaHttpServletResponse orig = Mockito.mock(SlingJakartaHttpServletResponse.class);