Made sure the encoded cookie conforms to the RFC
This commit is contained in:
parent
eaca45eb8a
commit
701d8a8aaa
@ -35,18 +35,9 @@ public class CookieEncoder {
|
|||||||
|
|
||||||
private final Set<Cookie> cookies = new TreeSet<Cookie>();
|
private final Set<Cookie> cookies = new TreeSet<Cookie>();
|
||||||
private final boolean server;
|
private final boolean server;
|
||||||
private final String charset;
|
|
||||||
|
|
||||||
public CookieEncoder(boolean server) {
|
public CookieEncoder(boolean server) {
|
||||||
this(server, QueryStringDecoder.DEFAULT_CHARSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CookieEncoder(boolean server, String charset) {
|
|
||||||
if (charset == null) {
|
|
||||||
throw new NullPointerException("charset");
|
|
||||||
}
|
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.charset = charset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCookie(String name, String value) {
|
public void addCookie(String name, String value) {
|
||||||
@ -69,11 +60,11 @@ public class CookieEncoder {
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
for (Cookie cookie: cookies) {
|
for (Cookie cookie: cookies) {
|
||||||
add(sb, cookie.getName(), QueryStringEncoder.encodeComponent(cookie.getValue(), charset));
|
add(sb, cookie.getName(), cookie.getValue());
|
||||||
|
|
||||||
if (cookie.getMaxAge() >= 0) {
|
if (cookie.getMaxAge() >= 0) {
|
||||||
if (cookie.getVersion() == 0) {
|
if (cookie.getVersion() == 0) {
|
||||||
add(sb, CookieHeaderNames.EXPIRES,
|
addUnquoted(sb, CookieHeaderNames.EXPIRES,
|
||||||
new CookieDateFormat().format(
|
new CookieDateFormat().format(
|
||||||
new Date(System.currentTimeMillis() +
|
new Date(System.currentTimeMillis() +
|
||||||
cookie.getMaxAge() * 1000L)));
|
cookie.getMaxAge() * 1000L)));
|
||||||
@ -83,11 +74,19 @@ public class CookieEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cookie.getPath() != null) {
|
if (cookie.getPath() != null) {
|
||||||
add(sb, CookieHeaderNames.PATH, cookie.getPath());
|
if (cookie.getVersion() > 0) {
|
||||||
|
add(sb, CookieHeaderNames.PATH, cookie.getPath());
|
||||||
|
} else {
|
||||||
|
addUnquoted(sb, CookieHeaderNames.PATH, cookie.getPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cookie.getDomain() != null) {
|
if (cookie.getDomain() != null) {
|
||||||
add(sb, CookieHeaderNames.DOMAIN, cookie.getDomain());
|
if (cookie.getVersion() > 0) {
|
||||||
|
add(sb, CookieHeaderNames.DOMAIN, cookie.getDomain());
|
||||||
|
} else {
|
||||||
|
addUnquoted(sb, CookieHeaderNames.DOMAIN, cookie.getDomain());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (cookie.isSecure()) {
|
if (cookie.isSecure()) {
|
||||||
sb.append(CookieHeaderNames.SECURE);
|
sb.append(CookieHeaderNames.SECURE);
|
||||||
@ -134,7 +133,7 @@ public class CookieEncoder {
|
|||||||
add(sb, '$' + CookieHeaderNames.VERSION, 1);
|
add(sb, '$' + CookieHeaderNames.VERSION, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
add(sb, cookie.getName(), QueryStringEncoder.encodeComponent(cookie.getValue(), charset));
|
add(sb, cookie.getName(), cookie.getValue());
|
||||||
|
|
||||||
if (cookie.getPath() != null) {
|
if (cookie.getPath() != null) {
|
||||||
add(sb, '$' + CookieHeaderNames.PATH, cookie.getPath());
|
add(sb, '$' + CookieHeaderNames.PATH, cookie.getPath());
|
||||||
@ -165,6 +164,27 @@ public class CookieEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void add(StringBuilder sb, String name, String val) {
|
private static void add(StringBuilder sb, String name, String val) {
|
||||||
|
if (val == null) {
|
||||||
|
addQuoted(sb, name, "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < val.length(); i ++) {
|
||||||
|
char c = val.charAt(i);
|
||||||
|
switch (c) {
|
||||||
|
case '(': case ')': case '<': case '>': case '@': case ',':
|
||||||
|
case ';': case ':': case '"': case '/': case '[': case ']':
|
||||||
|
case '?': case '=': case '{': case '}': case ' ':
|
||||||
|
case '\t': case '\\':
|
||||||
|
addQuoted(sb, name, val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addUnquoted(sb, name, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addUnquoted(StringBuilder sb, String name, String val) {
|
||||||
sb.append(name);
|
sb.append(name);
|
||||||
sb.append((char) HttpCodecUtil.EQUALS);
|
sb.append((char) HttpCodecUtil.EQUALS);
|
||||||
sb.append(val);
|
sb.append(val);
|
||||||
@ -172,10 +192,14 @@ public class CookieEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void addQuoted(StringBuilder sb, String name, String val) {
|
private static void addQuoted(StringBuilder sb, String name, String val) {
|
||||||
|
if (val == null) {
|
||||||
|
val = "";
|
||||||
|
}
|
||||||
|
|
||||||
sb.append(name);
|
sb.append(name);
|
||||||
sb.append((char) HttpCodecUtil.EQUALS);
|
sb.append((char) HttpCodecUtil.EQUALS);
|
||||||
sb.append((char) HttpCodecUtil.DOUBLE_QUOTE);
|
sb.append((char) HttpCodecUtil.DOUBLE_QUOTE);
|
||||||
sb.append(val);
|
sb.append(val.replace("\\", "\\\\").replace("\"", "\\\""));
|
||||||
sb.append((char) HttpCodecUtil.DOUBLE_QUOTE);
|
sb.append((char) HttpCodecUtil.DOUBLE_QUOTE);
|
||||||
sb.append((char) HttpCodecUtil.SEMICOLON);
|
sb.append((char) HttpCodecUtil.SEMICOLON);
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ public class QueryStringDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static String decodeComponent(String s, String charset) {
|
private static String decodeComponent(String s, String charset) {
|
||||||
try {
|
try {
|
||||||
return URLDecoder.decode(s, charset);
|
return URLDecoder.decode(s, charset);
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
@ -92,7 +92,7 @@ public class QueryStringEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static String encodeComponent(String s, String charset) {
|
private static String encodeComponent(String s, String charset) {
|
||||||
try {
|
try {
|
||||||
return URLEncoder.encode(s, charset).replaceAll("\\+", "%20");
|
return URLEncoder.encode(s, charset).replaceAll("\\+", "%20");
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
@ -52,7 +52,7 @@ public class CookieEncoderTest {
|
|||||||
cookie.setPorts(80, 8080);
|
cookie.setPorts(80, 8080);
|
||||||
cookie.setSecure(true);
|
cookie.setSecure(true);
|
||||||
String encodedCookie = encoder.encode();
|
String encodedCookie = encoder.encode();
|
||||||
|
System.out.println(encodedCookie);
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
assertTrue(
|
assertTrue(
|
||||||
encodedCookie.equals(result.replace("XXX", df.format(new Date(currentTime + 50000)))) ||
|
encodedCookie.equals(result.replace("XXX", df.format(new Date(currentTime + 50000)))) ||
|
||||||
@ -61,7 +61,7 @@ public class CookieEncoderTest {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
public void testEncodingSingleCookieV1() {
|
public void testEncodingSingleCookieV1() {
|
||||||
String result = "myCookie=myValue;Max-Age=50;Path=/apathsomewhere;Domain=.adomainsomewhere;Secure;Comment=this is a Comment;Version=1";
|
String result = "myCookie=myValue;Max-Age=50;Path=\"/apathsomewhere\";Domain=.adomainsomewhere;Secure;Comment=\"this is a Comment\";Version=1";
|
||||||
Cookie cookie = new DefaultCookie("myCookie", "myValue");
|
Cookie cookie = new DefaultCookie("myCookie", "myValue");
|
||||||
CookieEncoder encoder = new CookieEncoder(true);
|
CookieEncoder encoder = new CookieEncoder(true);
|
||||||
encoder.addCookie(cookie);
|
encoder.addCookie(cookie);
|
||||||
@ -76,7 +76,7 @@ public class CookieEncoderTest {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
public void testEncodingSingleCookieV2() {
|
public void testEncodingSingleCookieV2() {
|
||||||
String result = "myCookie=myValue;Max-Age=50;Path=/apathsomewhere;Domain=.adomainsomewhere;Secure;Comment=this is a Comment;Version=1;CommentURL=\"http://aurl.com\";Port=\"80,8080\";Discard";
|
String result = "myCookie=myValue;Max-Age=50;Path=\"/apathsomewhere\";Domain=.adomainsomewhere;Secure;Comment=\"this is a Comment\";Version=1;CommentURL=\"http://aurl.com\";Port=\"80,8080\";Discard";
|
||||||
Cookie cookie = new DefaultCookie("myCookie", "myValue");
|
Cookie cookie = new DefaultCookie("myCookie", "myValue");
|
||||||
CookieEncoder encoder = new CookieEncoder(true);
|
CookieEncoder encoder = new CookieEncoder(true);
|
||||||
encoder.addCookie(cookie);
|
encoder.addCookie(cookie);
|
||||||
@ -95,8 +95,8 @@ public class CookieEncoderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncodingMultipleCookies() {
|
public void testEncodingMultipleCookies() {
|
||||||
String c1 = "myCookie=myValue;Max-Age=50;Path=/apathsomewhere;Domain=.adomainsomewhere;Secure;Comment=this is a Comment;Version=1;CommentURL=\"http://aurl.com\";Port=\"80,8080\";Discard;";
|
String c1 = "myCookie=myValue;Max-Age=50;Path=\"/apathsomewhere\";Domain=.adomainsomewhere;Secure;Comment=\"this is a Comment\";Version=1;CommentURL=\"http://aurl.com\";Port=\"80,8080\";Discard;";
|
||||||
String c2 = "myCookie2=myValue2;Path=/anotherpathsomewhere;Domain=.anotherdomainsomewhere;Comment=this is another Comment;Version=1;CommentURL=\"http://anotherurl.com\";";
|
String c2 = "myCookie2=myValue2;Path=\"/anotherpathsomewhere\";Domain=.anotherdomainsomewhere;Comment=\"this is another Comment\";Version=1;CommentURL=\"http://anotherurl.com\";";
|
||||||
String c3 = "myCookie3=myValue3;Version=1";
|
String c3 = "myCookie3=myValue3;Version=1";
|
||||||
CookieEncoder encoder = new CookieEncoder(true);
|
CookieEncoder encoder = new CookieEncoder(true);
|
||||||
Cookie cookie = new DefaultCookie("myCookie", "myValue");
|
Cookie cookie = new DefaultCookie("myCookie", "myValue");
|
||||||
|
Loading…
Reference in New Issue
Block a user