This is an automated email from the ASF dual-hosted git repository.
joerghoh pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-engine.git
The following commit(s) were added to refs/heads/master by this push:
new 46780d5 SLING-13351 make content-type handling consistent (#86)
46780d5 is described below
commit 46780d5710c7c7aa0647f9d52b5961c09cc9df8b
Author: Jörg Hoh <[email protected]>
AuthorDate: Mon Sep 21 13:33:41 2026 +0200
SLING-13351 make content-type handling consistent (#86)
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 | 58 ++++++++++++++++++++++
2 files changed, 72 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 e8a690c..be9d38e 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 51bd2b7..58ac359 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,64 @@ 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);
+
when(requestData.getRequestProgressTracker()).thenReturn(mock(RequestProgressTracker.class));
+ 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);