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 09:45:07 UTC
(sling-org-apache-sling-engine) 01/01: SLING-13352 support log/fail also for newer Servlet Versions
This is an automated email from the ASF dual-hosted git repository.
joerghoh pushed a commit to branch SLING-13352
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-engine.git
commit 6b16104ca3aad0e135d454e1a9b78dfa28d122df
Author: Joerg Hoh <jo...@apache.org>
AuthorDate: Wed Sep 16 11:40:49 2026 +0200
SLING-13352 support log/fail also for newer Servlet Versions
add support for these methods
* sendRedirect(String, int)
* sendRedirect(String, boolean)
* sendRedirect(String, int, boolean)
* setTrailerFields(Supplier<Map<String,String>>)
---
.../impl/SlingJakartaHttpServletResponseImpl.java | 58 ++++++++++++++++++++++
.../impl/SlingHttpServletResponseImplTest.java | 38 ++++++++++++++
2 files changed, 96 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..9784007 100644
--- a/src/main/java/org/apache/sling/engine/impl/SlingJakartaHttpServletResponseImpl.java
+++ b/src/main/java/org/apache/sling/engine/impl/SlingJakartaHttpServletResponseImpl.java
@@ -28,7 +28,9 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Optional;
+import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -297,6 +299,62 @@ public class SlingJakartaHttpServletResponseImpl extends HttpServletResponseWrap
}
}
+ /**
+ * Overridden to apply the same include protection as
+ * {@link #sendRedirect(String)}. Since Servlet API 6.1
+ * {@code HttpServletResponseWrapper} overrides every {@code sendRedirect}
+ * variant with a direct delegation to the wrapped response, so each new
+ * overload must be gated here explicitly - none of them dispatches
+ * through another override on this wrapper.
+ */
+ @Override
+ public void sendRedirect(final String location, final int sc) throws IOException {
+ if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("sendRedirect()");
+ this.committedReason = CommitReason.SEND_REDIRECT;
+ super.sendRedirect(location, sc);
+ }
+ }
+
+ /**
+ * Overridden to apply the same include protection as
+ * {@link #sendRedirect(String)}, see {@link #sendRedirect(String, int)}.
+ */
+ @Override
+ public void sendRedirect(final String location, final boolean clearBuffer) throws IOException {
+ if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("sendRedirect()");
+ this.committedReason = CommitReason.SEND_REDIRECT;
+ super.sendRedirect(location, clearBuffer);
+ }
+ }
+
+ /**
+ * Overridden to apply the same include protection as
+ * {@link #sendRedirect(String)}, see {@link #sendRedirect(String, int)}.
+ */
+ @Override
+ public void sendRedirect(final String location, final int sc, final boolean clearBuffer) throws IOException {
+ if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("sendRedirect()");
+ this.committedReason = CommitReason.SEND_REDIRECT;
+ super.sendRedirect(location, sc, clearBuffer);
+ }
+ }
+
+ /**
+ * Overridden to apply the include header protection: response trailer
+ * fields are headers as well and must not be settable by included
+ * servlets when header protection is enabled.
+ */
+ @Override
+ public void setTrailerFields(final Supplier<Map<String, String>> supplier) {
+ if (!this.isProtectHeadersOnInclude()) {
+ logHeaderModificationCallOnIncludeForMethod("setTrailerFields()");
+ super.setTrailerFields(supplier);
+ }
+ }
+
@Override
public void setDateHeader(final String name, final long value) {
if (!this.isProtectHeadersOnInclude()) {
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..06c845b 100644
--- a/src/test/java/org/apache/sling/engine/impl/SlingHttpServletResponseImplTest.java
+++ b/src/test/java/org/apache/sling/engine/impl/SlingHttpServletResponseImplTest.java
@@ -141,6 +141,44 @@ public class SlingHttpServletResponseImplTest {
Mockito.verify(spyInclude, never()).checkContentTypeOverride(Mockito.any());
}
+ @Test
+ public void testSendRedirectOverloadsProtectedOnInclude() throws IOException {
+ 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.setProtectHeadersOnInclude(true);
+
+ final HttpServletResponse include = new SlingJakartaHttpServletResponseImpl(requestData, orig);
+
+ include.sendRedirect("/target");
+ include.sendRedirect("/target", HttpServletResponse.SC_MOVED_PERMANENTLY);
+ include.sendRedirect("/target", false);
+ include.sendRedirect("/target", HttpServletResponse.SC_MOVED_PERMANENTLY, false);
+ include.setTrailerFields(java.util.Collections::emptyMap);
+
+ Mockito.verifyNoInteractions(orig);
+ }
+
+ @Test
+ public void testSendRedirectOverloadsDelegateWhenNotProtected() throws IOException {
+ 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));
+
+ final HttpServletResponse include = new SlingJakartaHttpServletResponseImpl(requestData, orig);
+
+ include.sendRedirect("/target", HttpServletResponse.SC_MOVED_PERMANENTLY);
+ include.sendRedirect("/target", true);
+ include.sendRedirect("/target", HttpServletResponse.SC_MOVED_PERMANENTLY, false);
+
+ Mockito.verify(orig, times(1)).sendRedirect("/target", HttpServletResponse.SC_MOVED_PERMANENTLY);
+ Mockito.verify(orig, times(1)).sendRedirect("/target", true);
+ Mockito.verify(orig, times(1)).sendRedirect("/target", HttpServletResponse.SC_MOVED_PERMANENTLY, false);
+ }
+
@Test
public void testNoViolationChecksOnCommittedResponseWhenSendError() throws IOException {
final SlingJakartaHttpServletResponse orig = Mockito.mock(SlingJakartaHttpServletResponse.class);