diff --git a/CHANGELOG.md b/CHANGELOG.md index ca131d319d..93c68e2f15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com) ### Added +- #3448 - Adding support for paths that should not use ErrorHandlerService - #3415 - Allow Robots.txt generation to serve different file by requested resource path - #3426 - Content Sync: view history of completed jobs - #3417 - Configurable recursion in Content Sync diff --git a/all/pom.xml b/all/pom.xml index 70fb6ad9b6..52b4e1d840 100644 --- a/all/pom.xml +++ b/all/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.7.1-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/bundle-cloud/pom.xml b/bundle-cloud/pom.xml index fdf3c234d0..9979ec063c 100644 --- a/bundle-cloud/pom.xml +++ b/bundle-cloud/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.7.1-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/bundle-onprem/pom.xml b/bundle-onprem/pom.xml index 19aacd310a..717381d10b 100644 --- a/bundle-onprem/pom.xml +++ b/bundle-onprem/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.7.1-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/bundle/pom.xml b/bundle/pom.xml index ea60e4cbfb..ee2868cbf1 100644 --- a/bundle/pom.xml +++ b/bundle/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.7.1-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/ErrorPageHandlerService.java b/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/ErrorPageHandlerService.java index d2c95d6d20..51386d3d85 100644 --- a/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/ErrorPageHandlerService.java +++ b/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/ErrorPageHandlerService.java @@ -130,4 +130,10 @@ public interface ErrorPageHandlerService { * @return true if check is enabled else false */ boolean isVanityDispatchCheckEnabled(); + + /** + * @param request The request + * @return True if the service should be used for this service/ False if it should not + */ + public boolean shouldRequestUseErrorPageHandler(SlingHttpServletRequest request); } diff --git a/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/impl/ErrorPageHandlerImpl.java b/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/impl/ErrorPageHandlerImpl.java index 96efe97d87..0336e200c8 100644 --- a/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/impl/ErrorPageHandlerImpl.java +++ b/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/impl/ErrorPageHandlerImpl.java @@ -26,12 +26,15 @@ import java.util.Dictionary; import java.util.HashSet; import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Stream; import javax.management.DynamicMBean; import javax.management.NotCompliantMBeanException; @@ -93,6 +96,8 @@ public final class ErrorPageHandlerImpl implements ErrorPageHandlerService { private static final String REDIRECT_TO_LOGIN = "redirect-to-login"; private static final String RESPOND_WITH_404 = "respond-with-404"; + public String[] excludedPaths = null; + /* Enable/Disable */ private static final boolean DEFAULT_ENABLED = true; @@ -239,6 +244,13 @@ public final class ErrorPageHandlerImpl implements ErrorPageHandlerService { value = {"png", "jpeg", "jpg", "gif"}) private static final String PROP_ERROR_IMAGE_EXTENSIONS = "error-images.extensions"; + @Property( + label = "Excluded pages from handler", + description = "A list of pages that should not be considered as applicable to this service", + cardinality = Integer.MAX_VALUE, + value = { "/content/test-site", "/content/dam/test"}) + private static final String EXCLUDED_PATHS_FROM_HANDLER = "error-page.exclusion-list"; + @Reference private ResourceResolverFactory resourceResolverFactory; @@ -832,6 +844,8 @@ private void configure(ComponentContext componentContext) { Dictionary config = componentContext.getProperties(); final String legacyPrefix = "prop."; + this.excludedPaths = PropertiesUtil.toStringArray(config.get(EXCLUDED_PATHS_FROM_HANDLER)); + this.enabled = PropertiesUtil.toBoolean(config.get(PROP_ENABLED), PropertiesUtil.toBoolean(config.get(legacyPrefix + PROP_ENABLED), DEFAULT_ENABLED)); @@ -1036,4 +1050,14 @@ public boolean isVanityDispatchCheckEnabled() { return this.vanityDispatchCheckEnabled; } + @Override + public boolean shouldRequestUseErrorPageHandler(SlingHttpServletRequest request) { + if (this.excludedPaths == null) { + return true; + } + + long result = Stream.of(this.excludedPaths).filter((item) -> request.getRequestURI().contains(item)).count(); + return (result == 0); + } + } diff --git a/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/package-info.java b/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/package-info.java index e4a33de327..75e926eddc 100644 --- a/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/package-info.java +++ b/bundle/src/main/java/com/adobe/acs/commons/errorpagehandler/package-info.java @@ -18,5 +18,5 @@ /** * Dynamic Error Page Handler. */ -@org.osgi.annotation.versioning.Version("1.3.1") +@org.osgi.annotation.versioning.Version("1.4.0") package com.adobe.acs.commons.errorpagehandler; \ No newline at end of file diff --git a/bundle/src/test/java/com/adobe/acs/commons/errorpagehandler/impl/ErrorPageHandlerImplTest.java b/bundle/src/test/java/com/adobe/acs/commons/errorpagehandler/impl/ErrorPageHandlerImplTest.java index 4393bdae7f..df7a3332bd 100644 --- a/bundle/src/test/java/com/adobe/acs/commons/errorpagehandler/impl/ErrorPageHandlerImplTest.java +++ b/bundle/src/test/java/com/adobe/acs/commons/errorpagehandler/impl/ErrorPageHandlerImplTest.java @@ -17,21 +17,24 @@ */ package com.adobe.acs.commons.errorpagehandler.impl; +import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.NonExistingResource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.testing.mock.sling.junit.SlingContext; import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import java.util.HashSet; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; @RunWith(MockitoJUnitRunner.class) public class ErrorPageHandlerImplTest { @@ -48,43 +51,53 @@ public void setup() { resourceResolver = context.resourceResolver(); request = context.request(); } - + /** - * Test {@link ErrorPageHandlerImpl#findErrorPage(org.apache.sling.api.SlingHttpServletRequest, org.apache.sling.api.resource.Resource)} + * Test + * {@link ErrorPageHandlerImpl#findErrorPage(org.apache.sling.api.SlingHttpServletRequest, org.apache.sling.api.resource.Resource)} * with a page without {@code jcr:content} node. */ @Test public void testFindErrorPage_withoutContent() { - assertEquals("/content/project/test/error-pages.html", new ErrorPageHandlerImpl().findErrorPage(request, resourceResolver.getResource("/content/project/test/page-without-content"))); + assertEquals("/content/project/test/error-pages.html", new ErrorPageHandlerImpl().findErrorPage(request, + resourceResolver.getResource("/content/project/test/page-without-content"))); } /** - * Test {@link ErrorPageHandlerImpl#findErrorPage(org.apache.sling.api.SlingHttpServletRequest, org.apache.sling.api.resource.Resource)} + * Test + * {@link ErrorPageHandlerImpl#findErrorPage(org.apache.sling.api.SlingHttpServletRequest, org.apache.sling.api.resource.Resource)} * with a page with direct configuration. */ @Test public void testFindErrorPage_withDirectConfig() { - assertEquals("/content/project/test/error-pages2.html", new ErrorPageHandlerImpl().findErrorPage(request, resourceResolver.getResource("/content/project/test/page-with-config"))); + assertEquals("/content/project/test/error-pages2.html", new ErrorPageHandlerImpl().findErrorPage(request, + resourceResolver.getResource("/content/project/test/page-with-config"))); } - + @Test public void testFindErrorPage_subResource() { - assertEquals("/content/project/test/error-pages.html", new ErrorPageHandlerImpl().findErrorPage(request, new NonExistingResource(resourceResolver, "/content/project/test/jcr:content/root/non-existing-resource"))); + assertEquals("/content/project/test/error-pages.html", + new ErrorPageHandlerImpl().findErrorPage(request, new NonExistingResource(resourceResolver, + "/content/project/test/jcr:content/root/non-existing-resource"))); } @Test public void testFindErrorPage_nonExistingPage() { - assertEquals("/content/project/test/error-pages.html", new ErrorPageHandlerImpl().findErrorPage(request, new NonExistingResource(resourceResolver, "/content/project/test/non-existing-page"))); + assertEquals("/content/project/test/error-pages.html", new ErrorPageHandlerImpl().findErrorPage(request, + new NonExistingResource(resourceResolver, "/content/project/test/non-existing-page"))); } @Test public void testFindErrorPage_nonExistingPageSubResource() { - assertEquals("/content/project/test/error-pages.html", new ErrorPageHandlerImpl().findErrorPage(request, new NonExistingResource(resourceResolver, "/content/project/test/non-existing-page/jcr:content/test1/test2"))); + assertEquals("/content/project/test/error-pages.html", + new ErrorPageHandlerImpl().findErrorPage(request, new NonExistingResource(resourceResolver, + "/content/project/test/non-existing-page/jcr:content/test1/test2"))); } @Test public void testFindErrorPage_nonExistingPageWithoutExtension() { - assertEquals("/content/project/test/error-pages.html", new ErrorPageHandlerImpl().findErrorPage(request, new NonExistingResource(resourceResolver, "/content/project/non-existing-page"))); + assertEquals("/content/project/test/error-pages.html", new ErrorPageHandlerImpl().findErrorPage(request, + new NonExistingResource(resourceResolver, "/content/project/non-existing-page"))); } @Test @@ -93,20 +106,45 @@ public void testFindErrorPage_JcrContent0() { new ErrorPageHandlerImpl().findErrorPage(request, new NonExistingResource(resourceResolver, "/content/project/jcr:content/non-existing"))); } + @Test public void testResetRequestAndResponse() { context.response().setStatus(200); context.request().setAttribute("com.day.cq.widget.HtmlLibraryManager.included", "Some prior clientlibs"); - context.request().setAttribute("com.adobe.granite.ui.clientlibs.HtmlLibraryManager.included", "Some prior clientlibs"); + context.request().setAttribute("com.adobe.granite.ui.clientlibs.HtmlLibraryManager.included", + "Some prior clientlibs"); context.request().setAttribute("com.day.cq.wcm.componentcontext", "some prior component context"); new ErrorPageHandlerImpl().resetRequestAndResponse(context.request(), context.response(), 500); assertEquals("true", context.response().getHeader("x-aem-error-pass")); assertEquals(500, context.response().getStatus()); - assertEquals(0, ((HashSet) context.request().getAttribute("com.day.cq.widget.HtmlLibraryManager.included")).size()); - assertEquals(0, ((HashSet) context.request().getAttribute("com.adobe.granite.ui.clientlibs.HtmlLibraryManager.included")).size()); + assertEquals(0, + ((HashSet) context.request().getAttribute("com.day.cq.widget.HtmlLibraryManager.included")) + .size()); + assertEquals(0, ((HashSet) context.request() + .getAttribute("com.adobe.granite.ui.clientlibs.HtmlLibraryManager.included")).size()); assertNull(context.request().getAttribute("com.day.cq.wcm.componentcontext")); } + + @Test + public void testPathExclusion_true() { + SlingHttpServletRequest request = Mockito.mock(SlingHttpServletRequest.class); + Mockito.when(request.getRequestURI()).thenReturn("/content"); + + ErrorPageHandlerImpl errorPageHandlerService = new ErrorPageHandlerImpl(); + errorPageHandlerService.excludedPaths = new String[]{"/content/test-page"}; + assertTrue(errorPageHandlerService.shouldRequestUseErrorPageHandler(request)); + } + + @Test + public void testPathExclusion_false() { + SlingHttpServletRequest request = Mockito.mock(SlingHttpServletRequest.class); + Mockito.when(request.getRequestURI()).thenReturn("/content/test-page/test1234"); + + ErrorPageHandlerImpl errorPageHandlerService = new ErrorPageHandlerImpl(); + errorPageHandlerService.excludedPaths = new String[]{"/content/test-page"}; + assertFalse(errorPageHandlerService.shouldRequestUseErrorPageHandler(request)); + } } \ No newline at end of file diff --git a/oakpal-checks/pom.xml b/oakpal-checks/pom.xml index 723f91fd11..d26965d3ae 100644 --- a/oakpal-checks/pom.xml +++ b/oakpal-checks/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.7.1-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index ac90779015..d70afd7788 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.7.1-SNAPSHOT + 6.8.0-SNAPSHOT pom ACS AEM Commons - Reactor Project diff --git a/ui.apps/pom.xml b/ui.apps/pom.xml index b4a554f710..35fecb6588 100644 --- a/ui.apps/pom.xml +++ b/ui.apps/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.7.1-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/404.jsp b/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/404.jsp index a1cef5d55f..616d8276d1 100644 --- a/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/404.jsp +++ b/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/404.jsp @@ -23,7 +23,7 @@ %><%@include file="/libs/foundation/global.jsp" %><% ErrorPageHandlerService errorPageHandlerService = sling.getService(ErrorPageHandlerService.class); - if (errorPageHandlerService != null && errorPageHandlerService.isEnabled()) { + if (errorPageHandlerService != null && errorPageHandlerService.isEnabled() && errorPageHandlerService.shouldRequestUseErrorPageHandler(slingRequest)) { // Handle ACS AEM Commons vanity logic if (errorPageHandlerService.isVanityDispatchCheckEnabled()){ diff --git a/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/default.jsp b/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/default.jsp index 3ca6fbc4b1..a15d5fd4d3 100644 --- a/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/default.jsp +++ b/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/default.jsp @@ -25,7 +25,7 @@ final ErrorPageHandlerService errorPageHandlerService = sling.getService(ErrorPageHandlerService.class); - if (errorPageHandlerService != null && errorPageHandlerService.isEnabled()) { + if (errorPageHandlerService != null && errorPageHandlerService.isEnabled() && && errorPageHandlerService.shouldRequestUseErrorPageHandler(slingRequest)) { final int status = errorPageHandlerService.getStatusCode(slingRequest); if (status >= SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR && diff --git a/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/preview/errormessage.jsp b/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/preview/errormessage.jsp index 7083b6cc88..957212913a 100644 --- a/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/preview/errormessage.jsp +++ b/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/errorpagehandler/preview/errormessage.jsp @@ -24,7 +24,7 @@ javax.servlet.http.HttpServletResponse" %><% final ErrorPageHandlerService errorPageHandlerService = sling.getService(ErrorPageHandlerService.class); - if (errorPageHandlerService == null || !errorPageHandlerService.isEnabled()) { + if (errorPageHandlerService == null || !errorPageHandlerService.isEnabled() || !errorPageHandlerService.shouldRequestUseErrorPageHandler(slingRequest)) { return; } diff --git a/ui.config/pom.xml b/ui.config/pom.xml index 49bb8b7029..6c0ae7594b 100644 --- a/ui.config/pom.xml +++ b/ui.config/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.7.1-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/ui.content/pom.xml b/ui.content/pom.xml index e0d5b589cb..c4fc18dff3 100644 --- a/ui.content/pom.xml +++ b/ui.content/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.7.1-SNAPSHOT + 6.8.0-SNAPSHOT