// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.jdisc.http;
import org.jboss.netty.handler.codec.http.CookieDecoder;
import org.jboss.netty.handler.codec.http.CookieEncoder;
import org.jboss.netty.handler.codec.http.DefaultCookie;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @author Einar M R Rosenvinge
*/
public class Cookie {
private final Set ports = new HashSet<>();
private String name;
private String value;
private String domain;
private String path;
private String comment;
private String commentUrl;
private long maxAgeMillis = TimeUnit.SECONDS.toMillis(Integer.MIN_VALUE);
private int version;
private boolean secure;
private boolean httpOnly;
private boolean discard;
public Cookie() {
}
public Cookie(Cookie cookie) {
ports.addAll(cookie.ports);
name = cookie.name;
value = cookie.value;
domain = cookie.domain;
path = cookie.path;
comment = cookie.comment;
commentUrl = cookie.commentUrl;
maxAgeMillis = cookie.maxAgeMillis;
version = cookie.version;
secure = cookie.secure;
httpOnly = cookie.httpOnly;
discard = cookie.discard;
}
public Cookie(String name, String value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public Cookie setName(String name) {
this.name = name;
return this;
}
public String getValue() {
return value;
}
public Cookie setValue(String value) {
this.value = value;
return this;
}
public String getDomain() {
return domain;
}
public Cookie setDomain(String domain) {
this.domain = domain;
return this;
}
public String getPath() {
return path;
}
public Cookie setPath(String path) {
this.path = path;
return this;
}
public String getComment() {
return comment;
}
public Cookie setComment(String comment) {
this.comment = comment;
return this;
}
public String getCommentURL() {
return getCommentUrl();
}
public Cookie setCommentURL(String commentUrl) {
return setCommentUrl(commentUrl);
}
public String getCommentUrl() {
return commentUrl;
}
public Cookie setCommentUrl(String commentUrl) {
this.commentUrl = commentUrl;
return this;
}
public int getMaxAge(TimeUnit unit) {
return (int)unit.convert(maxAgeMillis, TimeUnit.MILLISECONDS);
}
public Cookie setMaxAge(int maxAge, TimeUnit unit) {
this.maxAgeMillis = unit.toMillis(maxAge);
return this;
}
public int getVersion() {
return version;
}
public Cookie setVersion(int version) {
this.version = version;
return this;
}
public boolean isSecure() {
return secure;
}
public Cookie setSecure(boolean secure) {
this.secure = secure;
return this;
}
public boolean isHttpOnly() {
return httpOnly;
}
public Cookie setHttpOnly(boolean httpOnly) {
this.httpOnly = httpOnly;
return this;
}
public boolean isDiscard() {
return discard;
}
public Cookie setDiscard(boolean discard) {
this.discard = discard;
return this;
}
public Set ports() {
return ports;
}
@Override
public int hashCode() {
return ports.hashCode() + hashCode(name) + hashCode(value) + hashCode(domain) + hashCode(path) +
hashCode(comment) + hashCode(commentUrl) + Long.valueOf(maxAgeMillis).hashCode() +
Integer.valueOf(version).hashCode() + Boolean.valueOf(secure).hashCode() +
Boolean.valueOf(httpOnly).hashCode() + Boolean.valueOf(discard).hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Cookie)) {
return false;
}
Cookie rhs = (Cookie)obj;
if (!ports.equals(rhs.ports)) {
return false;
}
if (!equals(name, rhs.name)) {
return false;
}
if (!equals(value, rhs.value)) {
return false;
}
if (!equals(domain, rhs.domain)) {
return false;
}
if (!equals(path, rhs.path)) {
return false;
}
if (!equals(comment, rhs.comment)) {
return false;
}
if (!equals(commentUrl, rhs.commentUrl)) {
return false;
}
if (maxAgeMillis != rhs.maxAgeMillis) {
return false;
}
if (version != rhs.version) {
return false;
}
if (secure != rhs.secure) {
return false;
}
if (httpOnly != rhs.httpOnly) {
return false;
}
if (discard != rhs.discard) {
return false;
}
return true;
}
@Override
public String toString() {
StringBuilder ret = new StringBuilder();
ret.append(name).append("=").append(value);
return ret.toString();
}
public static String toCookieHeader(Iterable extends Cookie> cookies) {
return encodeCookies(cookies, false);
}
public static List fromCookieHeader(String headerVal) {
return decodeCookies(headerVal);
}
public static String toSetCookieHeader(Iterable extends Cookie> cookies) {
return encodeCookies(cookies, true);
}
public static List fromSetCookieHeader(String headerVal) {
return decodeCookies(headerVal);
}
private static String encodeCookies(Iterable extends Cookie> cookies, boolean server) {
CookieEncoder encoder = new org.jboss.netty.handler.codec.http.CookieEncoder(server);
for (Cookie cookie : cookies) {
org.jboss.netty.handler.codec.http.Cookie nettyCookie =
new DefaultCookie(String.valueOf(cookie.getName()), String.valueOf(cookie.getValue()));
nettyCookie.setComment(cookie.getComment());
nettyCookie.setCommentUrl(cookie.getCommentUrl());
nettyCookie.setDiscard(cookie.isDiscard());
nettyCookie.setDomain(cookie.getDomain());
nettyCookie.setHttpOnly(cookie.isHttpOnly());
nettyCookie.setMaxAge(cookie.getMaxAge(TimeUnit.SECONDS));
nettyCookie.setPath(cookie.getPath());
nettyCookie.setSecure(cookie.isSecure());
nettyCookie.setVersion(cookie.getVersion());
nettyCookie.setPorts(cookie.ports());
encoder.addCookie(nettyCookie);
}
return encoder.encode();
}
private static List decodeCookies(String str) {
CookieDecoder decoder = new CookieDecoder();
List ret = new LinkedList<>();
for (org.jboss.netty.handler.codec.http.Cookie nettyCookie : decoder.decode(str)) {
Cookie cookie = new Cookie();
cookie.setName(nettyCookie.getName());
cookie.setValue(nettyCookie.getValue());
cookie.setComment(nettyCookie.getComment());
cookie.setCommentUrl(nettyCookie.getCommentUrl());
cookie.setDiscard(nettyCookie.isDiscard());
cookie.setDomain(nettyCookie.getDomain());
cookie.setHttpOnly(nettyCookie.isHttpOnly());
cookie.setMaxAge(nettyCookie.getMaxAge(), TimeUnit.SECONDS);
cookie.setPath(nettyCookie.getPath());
cookie.setSecure(nettyCookie.isSecure());
cookie.setVersion(nettyCookie.getVersion());
cookie.ports().addAll(nettyCookie.getPorts());
ret.add(cookie);
}
return ret;
}
private static int hashCode(Object obj) {
if (obj == null) {
return 0;
}
return obj.hashCode();
}
private static boolean equals(Object lhs, Object rhs) {
if (lhs == null || rhs == null) {
return lhs == rhs;
}
return lhs.equals(rhs);
}
}