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 c6d0599 SLING-13352 support log/fail also for newer Servlet Versions
(#87)
c6d0599 is described below
commit c6d0599b6d31c6bc08b6b9b3f8f095d3b2a318df
Author: Jörg Hoh <[email protected]>
AuthorDate: Mon Sep 21 18:47:57 2026 +0200
SLING-13352 support log/fail also for newer Servlet Versions (#87)
* 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>>)
* SLING-13352 also add support for setCharacterEncoding()
* Revert "SLING-13352 also add support for setCharacterEncoding()"
This reverts commit 792a5fb1d20363b459c8cd2cbaa57461fef099cb.
---------
Co-authored-by: Joerg Hoh <[email protected]>
---
.../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 be9d38e..6a5099b 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;
@@ -305,6 +307,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 58ac359..8a339c8 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);