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);

Reply via email to