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 2b694ff SLING-13322 warnings on non-spec compliant behavior (#82)
2b694ff is described below
commit 2b694ff1558e4f4fd5f14c52e2156d6400e09215
Author: Jörg Hoh <[email protected]>
AuthorDate: Tue Sep 1 20:53:12 2026 +0200
SLING-13322 warnings on non-spec compliant behavior (#82)
log warnings when during an include a header-modifying operation is tried,
which is not
allowed by the Servlet spec.
---
.../impl/SlingJakartaHttpServletResponseImpl.java | 33 ++++++++++++++++++++++
.../impl/SlingHttpServletResponseImplTest.java | 2 ++
2 files changed, 35 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 4c197d4..406d39e 100644
---
a/src/main/java/org/apache/sling/engine/impl/SlingJakartaHttpServletResponseImpl.java
+++
b/src/main/java/org/apache/sling/engine/impl/SlingJakartaHttpServletResponseImpl.java
@@ -210,6 +210,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
explanation);
}
} else { // response is not yet committed, so the statuscode can be
changed
+ logHeaderModificationCallOnIncludeForMethod("setStatus");
super.setStatus(sc);
}
}
@@ -217,6 +218,9 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void reset() {
if (!this.isProtectHeadersOnInclude() || isError()) {
+ if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("reset");
+ }
super.reset();
} else {
// ignore if not committed: because we want the exception to be
thrown when the
@@ -231,6 +235,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void setContentLength(final int len) {
if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("setContentLength()");
super.setContentLength(len);
}
}
@@ -238,6 +243,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void setContentLengthLong(final long len) {
if (!this.isProtectHeadersOnInclude()) {
+
logHeaderModificationCallOnIncludeForMethod("setContentLengthLong()");
super.setContentLengthLong(len);
}
}
@@ -245,6 +251,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void setLocale(final Locale loc) {
if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("setLocale()");
super.setLocale(loc);
}
}
@@ -252,6 +259,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void addCookie(final Cookie cookie) {
if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("addCookie()");
super.addCookie(cookie);
}
}
@@ -259,6 +267,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void addDateHeader(final String name, final long value) {
if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("addDateHeader()");
super.addDateHeader(name, value);
}
}
@@ -266,6 +275,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void addHeader(final String name, final String value) {
if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("addHeader()");
super.addHeader(name, value);
}
}
@@ -273,6 +283,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void addIntHeader(final String name, final int value) {
if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("addIntHeader()");
super.addIntHeader(name, value);
}
}
@@ -280,6 +291,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void sendRedirect(final String location) throws IOException {
if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("sendRedirect");
this.committedReason = CommitReason.SEND_REDIRECT;
super.sendRedirect(location);
}
@@ -288,6 +300,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void setDateHeader(final String name, final long value) {
if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("setDateHeader()");
super.setDateHeader(name, value);
}
}
@@ -295,6 +308,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void setHeader(final String name, final String value) {
if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("setHeader()");
super.setHeader(name, value);
}
}
@@ -302,6 +316,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void setIntHeader(final String name, final int value) {
if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("setIntHeader()");
super.setIntHeader(name, value);
}
}
@@ -492,6 +507,23 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
allMessages);
}
+ /**
+ * log a message for calling a header-modifying API when called as part of
an include
+ * @param method the name of the method
+ */
+ private void logHeaderModificationCallOnIncludeForMethod(String method) {
+ if (isInclude()) {
+ String msg = String.format(
+ "Calling '%s' within an include is not compliant to the
Servlet spec (see SLING-13222)", method);
+ requestData.getRequestProgressTracker().log("WARN:" + msg);
+ if (!LOG.isDebugEnabled()) {
+ LOG.warn("{}; enable DEBUG logging to get the full
stacktrace", msg);
+ } else {
+ LOG.warn("{}; call trace: {} ", msg, getCurrentStackTrace());
+ }
+ }
+ }
+
private static class ContentTypeChangeException extends SlingException {
protected ContentTypeChangeException(String text) {
super(text);
@@ -510,6 +542,7 @@ public class SlingJakartaHttpServletResponseImpl extends
HttpServletResponseWrap
@Override
public void sendError(int status, String message) throws IOException {
if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("setError()");
checkCommitted();
this.committedReason = CommitReason.SEND_ERROR;
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 88845c7..b14bc5b 100644
---
a/src/test/java/org/apache/sling/engine/impl/SlingHttpServletResponseImplTest.java
+++
b/src/test/java/org/apache/sling/engine/impl/SlingHttpServletResponseImplTest.java
@@ -94,6 +94,7 @@ public class SlingHttpServletResponseImplTest {
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));
final SlingJakartaHttpServletResponseImpl include = new
SlingJakartaHttpServletResponseImpl(requestData, orig);
SlingJakartaHttpServletResponseImpl spyInclude = Mockito.spy(include);
@@ -113,6 +114,7 @@ public class SlingHttpServletResponseImplTest {
final DispatchingInfo info = new
DispatchingInfo(DispatcherType.INCLUDE);
when(requestData.getDispatchingInfo()).thenReturn(info);
when(requestData.getSlingRequestProcessor()).thenReturn(mock(SlingRequestProcessorImpl.class));
+
when(requestData.getRequestProgressTracker()).thenReturn(mock(RequestProgressTracker.class));
final SlingJakartaHttpServletResponseImpl include = new
SlingJakartaHttpServletResponseImpl(requestData, orig);
SlingJakartaHttpServletResponseImpl spyInclude = Mockito.spy(include);