package org.multibit.mbm.utils; import com.yammer.dropwizard.logging.Log; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; /** *  <p>Utility to provide the following to application:</p> *  <ul> *  <li>Provision of web cookie interface</li> *  </ul> * * @since 0.0.1 *   */ public class CookieUtils { private static final Log LOG = Log.forClass(CookieUtils.class); /** * Default is to last for 2 years */ private static int DEFAULT_AGE =365*2; /** * @param request The request * @param name The cookie name * * @return The value of the matching cookie (or null) */ public static String getCookieValue(HttpServletRequest request, String name) { String value = null; Cookie cookie = getCookie(request, name); if (cookie != null) { value = getCookieValue(cookie); } else { LOG.debug("No Cookie in the request"); } return value; } /** * @param request The request * @param name The cookie name * * @return The matching Cookie (or null) */ private static Cookie getCookie(HttpServletRequest request, String name) { Cookie cookies[] = request.getCookies(); if (cookies != null) { for (int i = 0; i < cookies.length; i++) { if (cookies[i].getName().equalsIgnoreCase(name)) { return cookies[i]; } } } return null; } /** * @param cookie The cookie * @return A clean value (URL decoded and stripped of double quotes) */ private static String getCookieValue(Cookie cookie) { String rawCookieValue; try { rawCookieValue=URLDecoder.decode(cookie.getValue(),"UTF-8"); } catch (UnsupportedEncodingException e) { LOG.warn("Platform does not support UTF-8"); rawCookieValue = cookie.getValue(); } return unquote(rawCookieValue); } /** * IE 1-9 only supports cookie version 0, everyone else version 1 * Version 0 has no quotes and uses URL encoding * Version 1 has quotes and does not use URL encoding * * See http://stackoverflow.com/a/7233959/396747 * @param rawCookieValue The raw cookie value * * @return cookie value without double quote */ private static String unquote(String rawCookieValue) { // Check for version 0 (quoted and no URL encoding typically from IE) if ((rawCookieValue != null) && rawCookieValue.startsWith("\"") && rawCookieValue.endsWith("\"")) { int last = rawCookieValue.length() - 1; rawCookieValue = rawCookieValue.substring(1, last); } return rawCookieValue; } /** * Provides a fluent interface to build a Cookie */ public static class CookieBuilder { private String name; private String value; private int maxAge=DEFAULT_AGE; private String path; private String domain; private boolean isBuilt = false; private CookieBuilder() { } /** * @return A new builder */ public static CookieBuilder newInstance() { return new CookieBuilder(); } /** * @param name The name of the cookie * @return The builder */ public CookieBuilder withName(String name) { this.name = name; return this; } /** * * @param value The value * @return The builder */ public CookieBuilder withValue(String value) { this.value = value; return this; } /** * @param maxAge The maximum age * @return The builder */ public CookieBuilder withMaxAge(int maxAge) { this.maxAge = maxAge; return this; } /** * * @param path The path to activate the cookie * @return The builder */ public CookieBuilder withPath(String path) { this.path = path; return this; } /** * @param domain The domain to which it belongs * @return The builder */ public CookieBuilder withDomain(String domain) { this.domain = domain; return this; } /** * @return The cookie */ public Cookie build() { validateState(); if (name==null) { throw new IllegalStateException("Name is a mandatory field"); } if (value==null) { throw new IllegalStateException("Value is a mandatory field"); } Cookie cookie = null; cookie = new Cookie(name, value); cookie.setMaxAge(maxAge); if ((path != null) && (path.length() > 0)) { cookie.setPath(path); } else { cookie.setPath("/"); } if ((domain != null) && (domain.length() > 0)) { cookie.setDomain(domain); } return cookie; } private void validateState() { if (isBuilt) { throw new IllegalStateException("Cookie has been built"); } } } }