Author: sergeyb
Date: Wed Sep 7 15:02:57 2011
New Revision: 1166212
URL: http://svn.apache.org/viewvc?rev=1166212&view=rev
Log:
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.4.x-fixes/ (props changed)
cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProvider.java
cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProviderTest.java
Propchange: cxf/branches/2.4.x-fixes/
------------------------------------------------------------------------------
svn:mergeinfo = /cxf/trunk:1166211
Propchange: cxf/branches/2.4.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified:
cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProvider.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProvider.java?rev=1166212&r1=1166211&r2=1166212&view=diff
==============================================================================
---
cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProvider.java
(original)
+++
cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProvider.java
Wed Sep 7 15:02:57 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.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProviderTest.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProviderTest.java?rev=1166212&r1=1166211&r2=1166212&view=diff
==============================================================================
---
cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProviderTest.java
(original)
+++
cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/CacheControlHeaderProviderTest.java
Wed Sep 7 15:02:57 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);