You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by as...@apache.org on 2015/08/28 11:11:29 UTC
svn commit: r1698280 - in /sling/trunk/contrib/extensions/security/src:
main/java/org/apache/sling/security/impl/ContentDispositionFilter.java
test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java
Author: asanso
Date: Fri Aug 28 09:11:29 2015
New Revision: 1698280
URL: http://svn.apache.org/r1698280
Log:
SLING-4973 - Add Content Disposition Excluded Paths
Modified:
sling/trunk/contrib/extensions/security/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java
sling/trunk/contrib/extensions/security/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java
Modified: sling/trunk/contrib/extensions/security/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/security/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java?rev=1698280&r1=1698279&r2=1698280&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/security/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java (original)
+++ sling/trunk/contrib/extensions/security/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java Fri Aug 28 09:11:29 2015
@@ -18,6 +18,7 @@ package org.apache.sling.security.impl;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
@@ -62,12 +63,18 @@ public class ContentDispositionFilter im
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Property(label = "Content Disposition Paths",
- description = "These paths are filtered by the filter. "+
+ description = "These paths are checked by the filter. "+
"Each entry is of the form 'path [ \":\" CSV of excluded content types ]'. " +
"Invalid entries are logged and ignored."
, unbounded = PropertyUnbounded.ARRAY, value = { "" })
private static final String PROP_CONTENT_DISPOSTION_PATHS = "sling.content.disposition.paths";
+ @Property(label = "Content Disposition Excluded Paths",
+ description = "These paths are excluded by the filter. "+
+ "Each entry is of the form 'path'. "
+ , unbounded = PropertyUnbounded.ARRAY, value = { "" })
+ private static final String PROP_CONTENT_DISPOSTION_EXCLUDED_PATHS = "sling.content.disposition.excluded.paths";
+
private static final boolean DEFAULT_ENABLE_CONTENT_DISPOSTION_ALL_PATHS = false;
@Property(boolValue = DEFAULT_ENABLE_CONTENT_DISPOSTION_ALL_PATHS ,
label = "Enable Content Disposition for all paths",
@@ -84,6 +91,8 @@ public class ContentDispositionFilter im
* Array of prefixes of paths
*/
private String[] contentDispositionPathsPfx;
+
+ Set contentDispositionExcludedPaths;
private Map<String, Set<String>> contentTypesMapping;
@@ -142,8 +151,13 @@ public class ContentDispositionFilter im
enableContentDispositionAllPaths = PropertiesUtil.toBoolean(props.get(PROP_ENABLE_CONTENT_DISPOSTION_ALL_PATHS),DEFAULT_ENABLE_CONTENT_DISPOSTION_ALL_PATHS);
- logger.info("Initialized. content disposition paths: {}, content disposition paths-pfx {}. Enable Content Disposition for all paths is set to {}", new Object[]{
- contentDispositionPaths, contentDispositionPathsPfx, enableContentDispositionAllPaths}
+
+ String[] contentDispostionExcludedPathsArray = PropertiesUtil.toStringArray(props.get(PROP_CONTENT_DISPOSTION_EXCLUDED_PATHS));
+
+ contentDispositionExcludedPaths = new HashSet<String>(Arrays.asList(contentDispostionExcludedPathsArray));
+
+ logger.info("Initialized. content disposition paths: {}, content disposition paths-pfx {}, content disposition excluded paths: {}. Enable Content Disposition for all paths is set to {}", new Object[]{
+ contentDispositionPaths, contentDispositionPathsPfx, contentDispositionExcludedPaths, enableContentDispositionAllPaths}
);
}
@@ -214,38 +228,41 @@ public class ContentDispositionFilter im
}
request.setAttribute(ATTRIBUTE_NAME, type);
Resource resource = request.getResource();
+ String resourcePath = resource.getPath();
- if (enableContentDispositionAllPaths) {
- setContentDisposition(resource);
- } else {
- String resourcePath = resource.getPath();
-
- boolean contentDispositionAdded = false;
- if (contentDispositionPaths.contains(resourcePath)) {
-
- if (contentTypesMapping.containsKey(resourcePath)) {
- Set <String> exceptions = contentTypesMapping.get(resourcePath);
- if (!exceptions.contains(type)) {
+ if (!contentDispositionExcludedPaths.contains(resourcePath)) {
+
+ if (enableContentDispositionAllPaths) {
+ setContentDisposition(resource);
+ } else {
+
+ boolean contentDispositionAdded = false;
+ if (contentDispositionPaths.contains(resourcePath)) {
+
+ if (contentTypesMapping.containsKey(resourcePath)) {
+ Set <String> exceptions = contentTypesMapping.get(resourcePath);
+ if (!exceptions.contains(type)) {
+ contentDispositionAdded = setContentDisposition(resource);
+ }
+ } else {
contentDispositionAdded = setContentDisposition(resource);
}
- } else {
- contentDispositionAdded = setContentDisposition(resource);
- }
- }
- if (!contentDispositionAdded) {
- for (String path : contentDispositionPathsPfx) {
- if (resourcePath.startsWith(path)) {
- if (contentTypesMapping.containsKey(path)) {
- Set <String> exceptions = contentTypesMapping.get(path);
- if (!exceptions.contains(type)) {
+ }
+ if (!contentDispositionAdded) {
+ for (String path : contentDispositionPathsPfx) {
+ if (resourcePath.startsWith(path)) {
+ if (contentTypesMapping.containsKey(path)) {
+ Set <String> exceptions = contentTypesMapping.get(path);
+ if (!exceptions.contains(type)) {
+ setContentDisposition(resource);
+ break;
+ }
+ } else {
setContentDisposition(resource);
break;
}
- } else {
- setContentDisposition(resource);
- break;
- }
+ }
}
}
}
Modified: sling/trunk/contrib/extensions/security/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/security/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java?rev=1698280&r1=1698279&r2=1698280&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/security/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java (original)
+++ sling/trunk/contrib/extensions/security/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java Fri Aug 28 09:11:29 2015
@@ -51,6 +51,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -74,6 +75,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -97,6 +99,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/libs", "/content/usergenerated/*"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -120,6 +123,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"*"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -143,6 +147,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/libs:*"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -166,6 +171,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/libs:text/html,text/plain","/content/usergenerated/*:image/jpeg"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -192,6 +198,46 @@ public class ContentDispositionFilterTes
}
@Test
+ public void test_activator8() throws Throwable{
+ contentDispositionFilter = new ContentDispositionFilter();
+ final ComponentContext ctx = context.mock(ComponentContext.class);
+ final Dictionary props = new Hashtable<String, String[]>();
+ props.put("sling.content.disposition.paths", new String []{"/libs:text/html,text/plain","/content/usergenerated/*:image/jpeg"});
+ props.put("sling.content.disposition.excluded.paths", new String []{});
+
+ context.checking(new Expectations() {
+ {
+ allowing(ctx).getProperties();
+ will(returnValue(props));
+
+ }
+ });
+ PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx});
+ Set<String> contentDispositionExcludedPaths = ( Set<String> ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionExcludedPaths");
+ Assert.assertEquals(0, contentDispositionExcludedPaths.size());
+ }
+
+ @Test
+ public void test_activator9() throws Throwable{
+ contentDispositionFilter = new ContentDispositionFilter();
+ final ComponentContext ctx = context.mock(ComponentContext.class);
+ final Dictionary props = new Hashtable<String, String[]>();
+ props.put("sling.content.disposition.paths", new String []{"/libs:text/html,text/plain","/content/usergenerated/*:image/jpeg"});
+ props.put("sling.content.disposition.excluded.paths", new String []{"/content", "/libs"});
+
+ context.checking(new Expectations() {
+ {
+ allowing(ctx).getProperties();
+ will(returnValue(props));
+
+ }
+ });
+ PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx});
+ Set<String> contentDispositionExcludedPaths = ( Set<String> ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionExcludedPaths");
+ Assert.assertEquals(2, contentDispositionExcludedPaths.size());
+ }
+
+ @Test
public void test_getContentTypes() throws Throwable{
// null content types
String contentType = null;
@@ -220,6 +266,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -259,6 +306,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -298,6 +346,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -349,6 +398,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -389,6 +439,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -440,6 +491,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -490,6 +542,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated:text/html,text/plain"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -529,6 +582,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated:text/html,text/plain"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -567,6 +621,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated:text/html,text/plain"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -606,6 +661,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated:text/html,text/plain"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -656,6 +712,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*:text/html,text/plain"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -695,6 +752,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*:text/html,text/plain"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -733,6 +791,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*:text/html,text/plain"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -772,6 +831,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*:text/html,text/plain"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -828,6 +888,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -886,6 +947,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
context.checking(new Expectations() {
{
@@ -946,6 +1008,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
props.put("sling.content.disposition.all.paths", false);
context.checking(new Expectations() {
@@ -1006,6 +1069,7 @@ public class ContentDispositionFilterTes
final ComponentContext ctx = context.mock(ComponentContext.class);
final Dictionary props = new Hashtable<String, String[]>();
props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{""});
props.put("sling.content.disposition.all.paths", true);
context.checking(new Expectations() {
@@ -1055,6 +1119,232 @@ public class ContentDispositionFilterTes
}
@Test
+ public void test_doFilter19() throws Throwable{
+ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class);
+ final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class);
+ final Resource resource = context.mock(Resource.class, "resource" );
+ final ValueMap properties = context.mock(ValueMap.class);
+ contentDispositionFilter = new ContentDispositionFilter();
+
+ final ComponentContext ctx = context.mock(ComponentContext.class);
+ final Dictionary props = new Hashtable<String, String[]>();
+ props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{"/content"});
+ props.put("sling.content.disposition.all.paths", true);
+
+ context.checking(new Expectations() {
+ {
+ allowing(ctx).getProperties();
+ will(returnValue(props));
+
+ }
+ });
+ PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx});
+ final AtomicInteger counter = new AtomicInteger();
+ final ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response) {
+ public void addHeader(String name, String value) {
+ counter.incrementAndGet();
+ }
+ };
+
+
+ context.checking(new Expectations() {
+ {
+ exactly(1).of(response).containsHeader("Content-Disposition");
+ will(returnValue(false));
+ exactly(1).of(response).containsHeader("Content-Disposition");
+ will(returnValue(true));
+ exactly(1).of(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME);
+ will(returnValue(null));
+ exactly(1).of(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME);
+ will(returnValue("text/html"));
+ allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/xml");
+ allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html");
+ allowing(request).getResource();
+ will(returnValue(resource));
+ allowing(resource).getPath();
+ will(returnValue("/content/other"));
+ allowing(resource).adaptTo(ValueMap.class);
+ will(returnValue(properties));
+ allowing(properties).containsKey(PROP_JCR_DATA);
+ will(returnValue(true));
+ allowing(response).setContentType("text/html");
+ allowing(response).setContentType("text/xml");
+ //CONTENT DISPOSITION IS SET
+ exactly(1).of(response).addHeader("Content-Disposition", "attachment");
+ }
+ });
+ rewriterResponse.setContentType("text/html");
+ Assert.assertEquals(1, counter.intValue());
+ }
+
+ @Test
+ public void test_doFilter20() throws Throwable{
+ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class);
+ final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class);
+ final Resource resource = context.mock(Resource.class, "resource" );
+ final ValueMap properties = context.mock(ValueMap.class);
+ contentDispositionFilter = new ContentDispositionFilter();
+
+ final ComponentContext ctx = context.mock(ComponentContext.class);
+ final Dictionary props = new Hashtable<String, String[]>();
+ props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{"/content/other"});
+ props.put("sling.content.disposition.all.paths", true);
+
+ context.checking(new Expectations() {
+ {
+ allowing(ctx).getProperties();
+ will(returnValue(props));
+
+ }
+ });
+ PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx});
+ final AtomicInteger counter = new AtomicInteger();
+ final ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response) {
+ public void addHeader(String name, String value) {
+ counter.incrementAndGet();
+ }
+ };
+
+
+ context.checking(new Expectations() {
+ {
+ exactly(1).of(response).containsHeader("Content-Disposition");
+ will(returnValue(false));
+ exactly(1).of(response).containsHeader("Content-Disposition");
+ will(returnValue(true));
+ exactly(1).of(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME);
+ will(returnValue(null));
+ exactly(1).of(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME);
+ will(returnValue("text/html"));
+ allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/xml");
+ allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html");
+ allowing(request).getResource();
+ will(returnValue(resource));
+ allowing(resource).getPath();
+ will(returnValue("/content/other"));
+ allowing(resource).adaptTo(ValueMap.class);
+ will(returnValue(properties));
+ allowing(properties).containsKey(PROP_JCR_DATA);
+ will(returnValue(true));
+ allowing(response).setContentType("text/html");
+ allowing(response).setContentType("text/xml");
+ //CONTENT DISPOSITION IS NOT SET
+ never(response).addHeader("Content-Disposition", "attachment");
+ }
+ });
+ rewriterResponse.setContentType("text/html");
+ Assert.assertEquals(0, counter.intValue());
+ }
+
+ @Test
+ public void test_doFilter21() throws Throwable{
+ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class);
+ final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class);
+ final Resource resource = context.mock(Resource.class, "resource" );
+ final ValueMap properties = context.mock(ValueMap.class);
+ contentDispositionFilter = new ContentDispositionFilter();
+
+ final ComponentContext ctx = context.mock(ComponentContext.class);
+ final Dictionary props = new Hashtable<String, String[]>();
+ props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{"/content"});
+
+ context.checking(new Expectations() {
+ {
+ allowing(ctx).getProperties();
+ will(returnValue(props));
+
+ }
+ });
+ PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx});
+
+ final AtomicInteger counter = new AtomicInteger();
+ final ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response) {
+ public void addHeader(String name, String value) {
+ counter.incrementAndGet();
+ }
+ };
+
+ context.checking(new Expectations() {
+ {
+ allowing(response).containsHeader("Content-Disposition");
+ will(returnValue(false));
+ allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME);
+ will(returnValue(null));
+ allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html");
+ allowing(request).getResource();
+ will(returnValue(resource));
+ allowing(resource).getPath();
+ will(returnValue("/content/usergenerated"));
+ allowing(resource).adaptTo(ValueMap.class);
+ will(returnValue(properties));
+ allowing(properties).containsKey(PROP_JCR_DATA);
+ will(returnValue(true));
+ allowing(response).setContentType("text/html");
+ //CONTENT DISPOSITION IS SET
+ exactly(1).of(response).addHeader("Content-Disposition", "attachment");
+ }
+ });
+ rewriterResponse.setContentType("text/html");
+ Assert.assertEquals(1, counter.intValue());
+ }
+
+ @Test
+ public void test_doFilter22() throws Throwable{
+ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class);
+ final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class);
+ final Resource resource = context.mock(Resource.class, "resource" );
+ final ValueMap properties = context.mock(ValueMap.class);
+ contentDispositionFilter = new ContentDispositionFilter();
+
+ final ComponentContext ctx = context.mock(ComponentContext.class);
+ final Dictionary props = new Hashtable<String, String[]>();
+ props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"});
+ props.put("sling.content.disposition.excluded.paths", new String []{"/content/usergenerated"});
+
+ context.checking(new Expectations() {
+ {
+ allowing(ctx).getProperties();
+ will(returnValue(props));
+
+ }
+ });
+ PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx});
+
+ final AtomicInteger counter = new AtomicInteger();
+ final ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response) {
+ public void addHeader(String name, String value) {
+ counter.incrementAndGet();
+ }
+ };
+
+ context.checking(new Expectations() {
+ {
+ allowing(response).containsHeader("Content-Disposition");
+ will(returnValue(false));
+ allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME);
+ will(returnValue(null));
+ allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html");
+ allowing(request).getResource();
+ will(returnValue(resource));
+ allowing(resource).getPath();
+ will(returnValue("/content/usergenerated"));
+ allowing(resource).adaptTo(ValueMap.class);
+ will(returnValue(properties));
+ allowing(properties).containsKey(PROP_JCR_DATA);
+ will(returnValue(true));
+ allowing(response).setContentType("text/html");
+ //CONTENT DISPOSITION IS NOT SET
+ never(response).addHeader("Content-Disposition", "attachment");
+ }
+ });
+ rewriterResponse.setContentType("text/html");
+ Assert.assertEquals(0, counter.intValue());
+ }
+
+ @Test
public void test_isJcrData1() throws Throwable {
contentDispositionFilter = new ContentDispositionFilter();
final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class);