Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6A58118536 for ; Thu, 14 Jan 2016 02:20:23 +0000 (UTC) Received: (qmail 41349 invoked by uid 500); 14 Jan 2016 02:20:23 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 41282 invoked by uid 500); 14 Jan 2016 02:20:23 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 41269 invoked by uid 99); 14 Jan 2016 02:20:23 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 14 Jan 2016 02:20:22 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id CD36CE3849; Thu, 14 Jan 2016 02:20:22 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: irisding@apache.org To: commits@cxf.apache.org Date: Thu, 14 Jan 2016 02:20:22 -0000 Message-Id: <981451c6e18b44dcb9ab51310285ab8e@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/2] cxf git commit: cxf-6729 provide cookie version1 support Repository: cxf Updated Branches: refs/heads/master bc948f0ac -> f17f92319 cxf-6729 provide cookie version1 support Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/543644a3 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/543644a3 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/543644a3 Branch: refs/heads/master Commit: 543644a3404db8a3a556586109653ac478474658 Parents: fa0eea8 Author: irisding Authored: Wed Jan 13 17:22:47 2016 +0800 Committer: irisding Committed: Wed Jan 13 17:22:47 2016 +0800 ---------------------------------------------------------------------- .../cxf/jaxrs/impl/NewCookieHeaderProvider.java | 74 ++++++++++++++++++-- .../jaxrs/impl/NewCookieHeaderProviderTest.java | 24 ++++++- 2 files changed, 91 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/543644a3/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/NewCookieHeaderProvider.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/NewCookieHeaderProvider.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/NewCookieHeaderProvider.java index 15ba505..5a5a472 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/NewCookieHeaderProvider.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/NewCookieHeaderProvider.java @@ -37,6 +37,9 @@ public class NewCookieHeaderProvider implements HeaderDelegate { private static final String SECURE = "Secure"; private static final String EXPIRES = "Expires"; private static final String HTTP_ONLY = "HttpOnly"; + + /** from RFC 2068, token special case characters */ + private static final String TSPECIALS = "\"()<>@,;:\\/[]?={} \t"; public NewCookie fromString(String c) { @@ -63,6 +66,9 @@ public class NewCookieHeaderProvider implements HeaderDelegate { String paramName = sepIndex != -1 ? theToken.substring(0, sepIndex) : theToken; String paramValue = sepIndex == -1 || sepIndex == theToken.length() - 1 ? null : theToken.substring(sepIndex + 1); + if (paramValue != null && paramValue.startsWith("\"")) { + paramValue = paramValue.substring(1, paramValue.length() - 1); + } if (paramName.equalsIgnoreCase(MAX_AGE)) { maxAge = Integer.parseInt(paramValue); @@ -92,21 +98,27 @@ public class NewCookieHeaderProvider implements HeaderDelegate { return new NewCookie(name, value, path, domain, version, comment, maxAge, expires, isSecure, httpOnly); } - + + @Override public String toString(NewCookie value) { + + if (null == value) { + throw new NullPointerException("Null cookie input"); + } + StringBuilder sb = new StringBuilder(); - sb.append(value.getName()).append('=').append(value.getValue()); + sb.append(value.getName()).append('=').append(maybeQuote(value.getValue())); if (value.getComment() != null) { - sb.append(';').append(COMMENT).append('=').append(value.getComment()); + sb.append(';').append(COMMENT).append('=').append(maybeQuote(value.getComment())); } if (value.getDomain() != null) { - sb.append(';').append(DOMAIN).append('=').append(value.getDomain()); + sb.append(';').append(DOMAIN).append('=').append(maybeQuote(value.getDomain())); } if (value.getMaxAge() != -1) { sb.append(';').append(MAX_AGE).append('=').append(value.getMaxAge()); } if (value.getPath() != null) { - sb.append(';').append(PATH).append('=').append(value.getPath()); + sb.append(';').append(PATH).append('=').append(maybeQuote(value.getPath())); } if (value.getExpiry() != null) { sb.append(';').append(EXPIRES).append('=').append(HttpUtils.toHttpDate(value.getExpiry())); @@ -119,6 +131,58 @@ public class NewCookieHeaderProvider implements HeaderDelegate { } sb.append(';').append(VERSION).append('=').append(value.getVersion()); return sb.toString(); + + } + + /** + * Append the input value string to the given buffer, wrapping it with + * quotes if need be. + * + * @param value + * @return String + */ + private static String maybeQuote(String value) { + + StringBuilder buff = new StringBuilder(); + // handle a null value as well as an empty one, attr= + if (null == value || 0 == value.length()) { + buff.append(""); + } else if (needsQuote(value)) { + buff.append('"'); + buff.append(value); + buff.append('"'); + } else { + buff.append(value); + } + return buff.toString(); } + /** + * Return true iff the string contains special characters that need to be + * quoted. + * + * @param value + * @return boolean + */ + private static boolean needsQuote(String value) { + if (null == value) { + return true; + } + int len = value.length(); + if (0 == len) { + return true; + } + if ('"' == value.charAt(0) & '"' == value.charAt(len - 1)) { + // already wrapped with quotes + return false; + } + + for (int i = 0; i < len; i++) { + char c = value.charAt(i); + if (c < 0x20 || c >= 0x7f || TSPECIALS.indexOf(c) != -1) { + return true; + } + } + return false; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/543644a3/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/NewCookieHeaderProviderTest.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/NewCookieHeaderProviderTest.java b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/NewCookieHeaderProviderTest.java index 5f54f24..f04aac6 100644 --- a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/NewCookieHeaderProviderTest.java +++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/NewCookieHeaderProviderTest.java @@ -110,11 +110,31 @@ public class NewCookieHeaderProviderTest extends Assert { } @Test + public void testFromStringWithSpecialChar() { + NewCookie c = NewCookie.valueOf( + "foo=\"bar (space)<>[]\"; Comment=\"comment@comment:,\"; Path=\"/path?path\"; Max-Age=10; " + + "Domain=\"domain.com\"; Secure; Version=1"); + assertTrue("bar (space)<>[]".equals(c.getValue()) + && "foo".equals(c.getName()) + && 1 == c.getVersion() + && "/path?path".equals(c.getPath()) + && "domain.com".equals(c.getDomain()) + && "comment@comment:,".equals(c.getComment()) + && 10 == c.getMaxAge()); + } + + @Test public void testToString() { NewCookie c = new NewCookie("foo", "bar", "path", "domain", "comment", 2, true); assertEquals("foo=bar;Comment=comment;Domain=domain;Max-Age=2;Path=path;Secure;Version=1", - c.toString()); - + c.toString()); + } + + @Test + public void testToStringWithSpecialChar() { + NewCookie c = new NewCookie("foo", "bar (space)<>[]", "/path?path", "domain.com", "comment@comment:,", 2, true); + assertEquals("foo=\"bar (space)<>[]\";Comment=\"comment@comment:,\";Domain=domain.com;Max-Age=2;" + + "Path=\"/path?path\";Secure;Version=1", c.toString()); } }