This is an automated email from the ASF dual-hosted git repository. pedrosans pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/wicket.git
commit d2dbf39ba070ece659f231a182de302d720e7c9b Author: Schäfer, H.H. (Hans Hosea) <[email protected]> AuthorDate: Tue Sep 8 13:12:59 2026 +0200 WICKET-7205: Resolve IRequestHandlerDelegate-Chain in CSP-Processing Only the test is carried over to master. Here a page writes its own CSP headers from WebPage#configureResponse without looking at the request handler, so there is no delegate chain to resolve; the test guards that a page reached through nested delegates keeps its headers. (cherry picked from commit 00f2e01032023a67da610906094095317984eb5d) --- .../org/apache/wicket/csp/CSPHeaderWriterTest.java | 53 ++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/wicket-core-tests/src/test/java/org/apache/wicket/csp/CSPHeaderWriterTest.java b/wicket-core-tests/src/test/java/org/apache/wicket/csp/CSPHeaderWriterTest.java index f7afcce72d..a2034c8d12 100644 --- a/wicket-core-tests/src/test/java/org/apache/wicket/csp/CSPHeaderWriterTest.java +++ b/wicket-core-tests/src/test/java/org/apache/wicket/csp/CSPHeaderWriterTest.java @@ -20,12 +20,18 @@ import org.apache.wicket.MarkupContainer; import org.apache.wicket.RestartResponseException; import org.apache.wicket.core.request.handler.PageProvider; import org.apache.wicket.core.request.handler.RenderPageRequestHandler; +import org.apache.wicket.core.request.mapper.MountedMapper; import org.apache.wicket.markup.IMarkupResourceStreamProvider; import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.html.WebPage; +import org.apache.wicket.markup.html.form.login.MockHomePage; import org.apache.wicket.markup.html.link.StatelessLink; import org.apache.wicket.protocol.http.mock.MockHttpServletResponse; +import org.apache.wicket.request.IRequestCycle; +import org.apache.wicket.request.IRequestHandler; +import org.apache.wicket.request.IRequestHandlerDelegate; +import org.apache.wicket.request.Request; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.request.resource.CssResourceReference; import org.apache.wicket.util.resource.IResourceStream; @@ -120,6 +126,53 @@ class CSPHeaderWriterTest extends WicketTestCase STYLE_SRC.getValue()); } + @Test + void addCspDirectiveToStatelessPageEvenIfWrappedInMultipleIRequestHandlerDelegates() + { + tester.getApplication().mount(new MountedMapper("withdelegate/page", NoopMockPage.class) + { + @Override + public IRequestHandler mapRequest(final Request request) + { + final IRequestHandler requestHandler = super.mapRequest(request); + final IRequestHandler result; + if (requestHandler instanceof RenderPageRequestHandler renderPageRequestHandler && NoopMockPage.class.equals(renderPageRequestHandler.getPageClass())) + { + result = new NoopIRequestHandlerDelegate(new NoopIRequestHandlerDelegate(renderPageRequestHandler)); + } else { + result = requestHandler; + } + return result; + } + }); + tester.startPage(NoopMockPage.class); + + assertThat(tester.getLastRenderedPage()).isInstanceOf(NoopMockPage.class); + assertThat(tester.getLastResponse().getHeader("Content-Security-Policy")).contains( + STYLE_SRC.getValue()); + } + + public static class NoopMockPage extends MockHomePage { + } + + static class NoopIRequestHandlerDelegate implements IRequestHandlerDelegate { + private final IRequestHandler delegate; + + NoopIRequestHandlerDelegate(final IRequestHandler delegate) { + this.delegate = delegate; + } + + @Override + public IRequestHandler getDelegateHandler() { + return delegate; + } + + @Override + public void respond(final IRequestCycle requestCycle) { + delegate.respond(requestCycle); + } + } + public static class Page extends WebPage implements IMarkupResourceStreamProvider { @Override
