Author: sergeyb Date: Wed Sep 7 15:08:49 2011 New Revision: 1166213 URL: http://svn.apache.org/viewvc?rev=1166213&view=rev Log: Merged revisions 1166212 via svnmerge from https://svn.apache.org/repos/asf/cxf/branches/2.4.x-fixes
................ r1166212 | sergeyb | 2011-09-07 16:02:57 +0100 (Wed, 07 Sep 2011) | 9 lines Merged revisions 1166211 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk ........ r1166211 | sergeyb | 2011-09-07 15:59:19 +0100 (Wed, 07 Sep 2011) | 1 line [CXF-3775] Better support for Cache-Control private and no-cache fields ........ ................ Modified: cxf/branches/2.3.x-fixes/ (props changed) cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProvider.java cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProviderTest.java Propchange: cxf/branches/2.3.x-fixes/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Wed Sep 7 15:08:49 2011 @@ -1,2 +1,2 @@ -/cxf/branches/2.4.x-fixes:1164609 -/cxf/trunk:1164536 +/cxf/branches/2.4.x-fixes:1164609,1166212 +/cxf/trunk:1164536,1166211 Propchange: cxf/branches/2.3.x-fixes/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Modified: cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProvider.java?rev=1166213&r1=1166212&r2=1166213&view=diff ============================================================================== --- cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProvider.java (original) +++ cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProvider.java Wed Sep 7 15:08:49 2011 @@ -20,9 +20,12 @@ package org.apache.cxf.jaxrs.impl; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.ws.rs.core.CacheControl; import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate; @@ -36,6 +39,11 @@ public class CacheControlHeaderProvider "org.apache.cxf.http.cache-control.separator"; private static final String DEFAULT_SEPARATOR = ","; + private static final String COMPLEX_HEADER_EXPRESSION = + "(([\\w-]+=\"[^\"]*\")|([\\w-]+=[\\w]+)|([\\w-]+))"; + private static final Pattern COMPLEX_HEADER_PATTERN = + Pattern.compile(COMPLEX_HEADER_EXPRESSION); + private static final String PUBLIC = "public"; private static final String PRIVATE = "private"; private static final String NO_CACHE = "no-cache"; @@ -57,10 +65,9 @@ public class CacheControlHeaderProvider boolean proxyRevalidate = false; int maxAge = -1; int sMaxAge = -1; - - String separator = getSeparator(); + Map<String, String> extensions = new HashMap<String, String>(); - String[] tokens = c.split(separator); + String[] tokens = getTokens(c); for (String rawToken : tokens) { String token = rawToken.trim(); if (token.startsWith(MAX_AGE)) { @@ -83,6 +90,10 @@ public class CacheControlHeaderProvider } else if (token.startsWith(NO_CACHE)) { noCache = true; addFields(noCacheFields, token); + } else { + String[] extPair = token.split("="); + String value = extPair.length == 2 ? extPair[1] : ""; + extensions.put(extPair[0], value); } } @@ -97,10 +108,28 @@ public class CacheControlHeaderProvider cc.getNoCacheFields().addAll(noCacheFields); cc.setNoStore(noStore); cc.setNoTransform(noTransform); + cc.getCacheExtension().putAll(extensions); return cc; } + private String[] getTokens(String c) { + if (c.contains("\"")) { + List<String> values = new ArrayList<String>(4); + Matcher m = COMPLEX_HEADER_PATTERN.matcher(c); + while (m.find()) { + String val = m.group().trim(); + if (val.length() > 0) { + values.add(val); + } + } + return values.toArray(new String[]{}); + } else { + String separator = getSeparator(); + return c.split(separator); + } + } + public String toString(CacheControl c) { String separator = getSeparator(); @@ -152,19 +181,22 @@ public class CacheControlHeaderProvider } private static void addFields(List<String> fields, String token) { - String f = null; int i = token.indexOf('='); if (i != -1) { - f = i == token.length() + 1 ? "" : token.substring(i + 1); + String f = i == token.length() + 1 ? "" : token.substring(i + 1); if (f.length() < 2 || !f.startsWith("\"") || !f.endsWith("\"")) { - f = ""; + return; } else { f = f.length() == 2 ? "" : f.substring(1, f.length() - 1); + if (f.length() > 0) { + String[] values = f.split(","); + for (String v : values) { + fields.add(v.trim()); + } + } } } - if (f != null) { - fields.add(f); - } + } private static void handleFields(List<String> fields, StringBuilder sb) { @@ -172,12 +204,14 @@ public class CacheControlHeaderProvider return; } sb.append('='); + sb.append('\"'); for (Iterator<String> it = fields.iterator(); it.hasNext();) { - sb.append('\"').append(it.next()).append('\"'); + sb.append(it.next()); if (it.hasNext()) { sb.append(','); } } + sb.append('\"'); } protected String getSeparator() { Modified: cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProviderTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProviderTest.java?rev=1166213&r1=1166212&r2=1166213&view=diff ============================================================================== --- cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProviderTest.java (original) +++ cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProviderTest.java Wed Sep 7 15:08:49 2011 @@ -19,11 +19,13 @@ package org.apache.cxf.jaxrs.impl; +import java.util.List; +import java.util.Map; + import javax.ws.rs.core.CacheControl; import org.apache.cxf.message.Message; import org.apache.cxf.message.MessageImpl; - import org.junit.Assert; import org.junit.Test; @@ -99,6 +101,54 @@ public class CacheControlHeaderProviderT } @Test + public void testMultiplePrivateFields() { + CacheControl cc = new CacheControl(); + cc.setPrivate(true); + cc.getPrivateFields().add("a"); + cc.getPrivateFields().add("b"); + assertTrue(cc.toString().contains("private=\"a,b\"")); + } + + @Test + public void testMultipleNoCacheFields() { + CacheControl cc = new CacheControl(); + cc.setNoCache(true); + cc.getNoCacheFields().add("c"); + cc.getNoCacheFields().add("d"); + assertTrue(cc.toString().contains("no-cache=\"c,d\"")); + } + + @Test + public void testReadMultiplePrivateAndNoCacheFields() { + String s = "private=\"foo1,foo2\",no-store,no-transform," + + "must-revalidate,proxy-revalidate,max-age=2,s-maxage=3,no-cache=\"bar1,bar2\"," + + "ext=1"; + CacheControl cc = CacheControl.valueOf(s); + + assertTrue(cc.isPrivate()); + List<String> privateFields = cc.getPrivateFields(); + assertEquals(2, privateFields.size()); + assertEquals("foo1", privateFields.get(0)); + assertEquals("foo2", privateFields.get(1)); + assertTrue(cc.isNoCache()); + List<String> noCacheFields = cc.getNoCacheFields(); + assertEquals(2, noCacheFields.size()); + assertEquals("bar1", noCacheFields.get(0)); + assertEquals("bar2", noCacheFields.get(1)); + + assertTrue(cc.isNoStore()); + assertTrue(cc.isNoTransform()); + assertTrue(cc.isMustRevalidate()); + assertTrue(cc.isProxyRevalidate()); + assertEquals(2, cc.getMaxAge()); + assertEquals(3, cc.getSMaxAge()); + + Map<String, String> exts = cc.getCacheExtension(); + assertEquals(1, exts.size()); + assertEquals("1", exts.get("ext")); + } + + @Test public void testCacheExtensionToString() { CacheControl cc = new CacheControl(); cc.getCacheExtension().put("ext1", null);
