You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CookieManager.java 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. package com.google.gwt.query.vm;
  2. import java.io.IOException;
  3. import java.net.URL;
  4. import java.net.URLConnection;
  5. import java.text.DateFormat;
  6. import java.text.SimpleDateFormat;
  7. import java.util.Date;
  8. import java.util.HashMap;
  9. import java.util.Iterator;
  10. import java.util.Map;
  11. import java.util.StringTokenizer;
  12. /**
  13. * @author Ian Brown spam@hccp.org
  14. * http://www.hccp.org/java-net-cookie-how-to.html
  15. */
  16. public class CookieManager {
  17. private Map<String,Map<String,Map<String, String>>> store = new HashMap<String, Map<String,Map<String, String>>>();
  18. private static final String SET_COOKIE = "Set-Cookie";
  19. private static final String COOKIE_VALUE_DELIMITER = ";";
  20. private static final String PATH = "path";
  21. private static final String EXPIRES = "expires";
  22. private static final String DATE_FORMAT = "EEE, dd-MMM-yyyy hh:mm:ss z";
  23. private static final String SET_COOKIE_SEPARATOR = "; ";
  24. private static final String COOKIE = "Cookie";
  25. private static final char NAME_VALUE_SEPARATOR = '=';
  26. private static final char DOT = '.';
  27. private DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);;
  28. private static CookieManager cookieManager = new CookieManager();
  29. public static CookieManager getInstance() {
  30. return cookieManager;
  31. }
  32. public void clear() {
  33. store.clear();
  34. }
  35. public void removeDomainCookies(String domain) {
  36. store.remove(domain);
  37. }
  38. public void removeDomainCookie(String domain, String... cookies) {
  39. Map<String, Map<String, String>> domainStore = store.get(domain);
  40. if (domainStore != null) {
  41. for (String cookie: cookies) {
  42. domainStore.remove(cookie);
  43. }
  44. }
  45. }
  46. public void setDomcainCookie(String host, String name, String value) {
  47. setDomcainCookieProperty(host, name, name, value);
  48. }
  49. public void setDomcainCookieProperty(String host, String name, String prop, String value) {
  50. String domain = getDomainFromHost(host);
  51. Map<String, Map<String, String>> domainStore = store.get(domain);
  52. if (domainStore == null) {
  53. domainStore = new HashMap<String, Map<String,String>>();
  54. store.put(domain, domainStore);
  55. }
  56. Map<String, String> cookie = domainStore.get(name);
  57. if (cookie == null) {
  58. cookie = new HashMap<String, String>();
  59. domainStore.put(name, cookie);
  60. }
  61. if (value == null) {
  62. cookie.remove(prop);
  63. } else {
  64. cookie.put(prop, value);
  65. }
  66. }
  67. /**
  68. * Retrieves and stores cookies returned by the host on the other side of the the open
  69. * java.net.URLConnection.
  70. *
  71. * The connection MUST have been opened using the connect() method or a IOException will be
  72. * thrown.
  73. *
  74. * @param conn a java.net.URLConnection - must be open, or IOException will be thrown
  75. * @throws java.io.IOException Thrown if conn is not open.
  76. */
  77. public void storeCookies(URLConnection conn) throws IOException {
  78. // let's determine the domain from where these cookies are being sent
  79. String domain = getDomainFromHost(conn.getURL().getHost());
  80. Map<String,Map<String, String>> domainStore; // this is where we will store cookies for this domain
  81. // now let's check the store to see if we have an entry for this domain
  82. if (store.containsKey(domain)) {
  83. // we do, so lets retrieve it from the store
  84. domainStore = store.get(domain);
  85. } else {
  86. // we don't, so let's create it and put it in the store
  87. domainStore = new HashMap<String, Map<String,String>>();
  88. store.put(domain, domainStore);
  89. }
  90. // OK, now we are ready to get the cookies out of the URLConnection
  91. String headerName = null;
  92. for (int i = 1; (headerName = conn.getHeaderFieldKey(i)) != null; i++) {
  93. if (headerName.equalsIgnoreCase(SET_COOKIE)) {
  94. Map<String, String> cookie = new HashMap<String, String>();
  95. StringTokenizer st = new StringTokenizer(conn.getHeaderField(i), COOKIE_VALUE_DELIMITER);
  96. // the specification dictates that the first name/value pair
  97. // in the string is the cookie name and value, so let's handle
  98. // them as a special case:
  99. if (st.hasMoreTokens()) {
  100. String token = st.nextToken();
  101. String name = token.substring(0, token.indexOf(NAME_VALUE_SEPARATOR));
  102. String value = token.substring(token.indexOf(NAME_VALUE_SEPARATOR) + 1, token.length());
  103. domainStore.put(name, cookie);
  104. cookie.put(name, value);
  105. }
  106. while (st.hasMoreTokens()) {
  107. String token = st.nextToken().toLowerCase();
  108. int idx = token.indexOf(NAME_VALUE_SEPARATOR);
  109. if (idx > 0 && idx < token.length() -1) {
  110. cookie.put(token.substring(0, idx).toLowerCase(), token.substring(idx + 1, token.length()));
  111. }
  112. }
  113. }
  114. }
  115. }
  116. /**
  117. * Prior to opening a URLConnection, calling this method will set all unexpired cookies that match
  118. * the path or subpaths for thi underlying URL
  119. *
  120. * The connection MUST NOT have been opened method or an IOException will be thrown.
  121. *
  122. * @param conn a java.net.URLConnection - must NOT be open, or IOException will be thrown
  123. * @throws java.io.IOException Thrown if conn has already been opened.
  124. */
  125. public void setCookies(URLConnection conn) throws IOException {
  126. // let's determine the domain and path to retrieve the appropriate cookies
  127. URL url = conn.getURL();
  128. String domain = getDomainFromHost(url.getHost());
  129. if (domain.equals("localhost")) {
  130. domain = "linkedin.com";
  131. }
  132. String path = url.getPath();
  133. Map<String, Map<String, String>> domainStore = store.get(domain);
  134. if (domainStore == null)
  135. return;
  136. StringBuffer cookieStringBuffer = new StringBuffer();
  137. Iterator<String> cookieNames = domainStore.keySet().iterator();
  138. while (cookieNames.hasNext()) {
  139. String cookieName = cookieNames.next();
  140. Map<String, String> cookie = domainStore.get(cookieName);
  141. // check cookie to ensure path matches and cookie is not expired
  142. // if all is cool, add cookie to header string
  143. if (comparePaths((String) cookie.get(PATH), path)
  144. && isNotExpired(cookie.get(EXPIRES))) {
  145. cookieStringBuffer.append(cookieName);
  146. cookieStringBuffer.append("=");
  147. cookieStringBuffer.append(cookie.get(cookieName));
  148. if (cookieNames.hasNext())
  149. cookieStringBuffer.append(SET_COOKIE_SEPARATOR);
  150. }
  151. }
  152. try {
  153. conn.setRequestProperty(COOKIE, cookieStringBuffer.toString());
  154. } catch (java.lang.IllegalStateException ise) {
  155. IOException ioe =
  156. new IOException(
  157. "Illegal State! Cookies cannot be set on a URLConnection that is already connected. "
  158. + "Only call setCookies(java.net.URLConnection) AFTER calling java.net.URLConnection.connect().");
  159. throw ioe;
  160. }
  161. }
  162. private String getDomainFromHost(String host) {
  163. host = host.toLowerCase().replaceFirst("https?://", "").replaceAll("[/?:].*$", "");
  164. if (host.indexOf(DOT) != host.lastIndexOf(DOT)) {
  165. return host.substring(host.indexOf(DOT) + 1);
  166. } else {
  167. return host;
  168. }
  169. }
  170. private boolean isNotExpired(String cookieExpires) {
  171. if (cookieExpires == null)
  172. return true;
  173. Date now = new Date();
  174. try {
  175. return (now.compareTo(dateFormat.parse(cookieExpires))) <= 0;
  176. } catch (java.text.ParseException pe) {
  177. pe.printStackTrace();
  178. return false;
  179. }
  180. }
  181. private boolean comparePaths(String cookiePath, String targetPath) {
  182. if (cookiePath == null) {
  183. return true;
  184. } else if (cookiePath.equals("/")) {
  185. return true;
  186. } else if (targetPath.regionMatches(0, cookiePath, 0, cookiePath.length())) {
  187. return true;
  188. } else {
  189. return false;
  190. }
  191. }
  192. public String toString() {
  193. return store.toString();
  194. }
  195. }