1 package net.matuschek.http.cookie; 2 3 import java.net.URL ; 4 import java.util.Date ; 5 import java.util.Locale ; 6 import java.util.StringTokenizer ; 7 10 11 12 19 public class Cookie 20 { 21 22 final static String HEADER_SETCOOKIE="Set-Cookie:"; 23 24 25 final static String HEADER_COOKIE="Cookie:"; 26 27 28 private String name; 29 30 31 private String value=null; 32 33 39 private long maxAge=-1; 40 41 42 private String comment=""; 43 44 45 private String domain=null; 46 47 48 private String path="/"; 49 50 51 private boolean secure=false; 52 53 57 private Date expireDate=new Date (Long.MAX_VALUE); 58 59 67 private int version=0; 68 69 70 73 public Cookie() { 74 } 75 76 77 86 public Cookie(String setCookie, URL u) 87 throws CookieException 88 { 89 this(); 90 91 String cookieHeader = null; 92 String host = ""; 93 StringTokenizer tokens = null; 94 95 if (setCookie.substring(0,HEADER_SETCOOKIE.length()).equalsIgnoreCase(HEADER_SETCOOKIE)) { 97 cookieHeader = setCookie.substring(HEADER_SETCOOKIE.length()); 98 } else { 99 throw new CookieException("Not a Set-Cookie header"); 100 } 101 102 if (u != null) { 104 this.domain = u.getHost().toLowerCase(); 105 host = this.domain; 106 } else { 107 this.domain = ""; 108 } 109 110 tokens = new StringTokenizer (cookieHeader,";"); 112 113 if (tokens.countTokens() < 1) { 115 throw new CookieException("Cookie contains no data"); 116 } else { 117 String field = tokens.nextToken(); 118 int pos = field.indexOf('='); 119 if (pos <= 0) { 120 throw new CookieException("First field not in the format NAME=VALUE" 121 +" but got "+field); 122 } else { 123 name = field.substring(0,pos).trim(); 124 value = field.substring(pos+1); 125 } 126 } 127 128 while (tokens.hasMoreTokens()) { 130 String field = tokens.nextToken(); 131 String fieldname=""; 132 String fieldvalue=""; 133 134 int pos = field.indexOf('='); 135 if (pos <= 0) { 136 fieldname = field.trim(); 137 fieldvalue=""; 138 } else { 139 fieldname = field.substring(0,pos).trim(); 140 fieldvalue = field.substring(pos+1).trim(); 141 } 142 143 if (fieldname.equalsIgnoreCase("comment")) { 144 this.comment = fieldvalue; 148 } else if (fieldname.equalsIgnoreCase("domain")) { 149 String domainvalue = fieldvalue.toLowerCase(); 153 if ((host.equals("")) 155 || (host.endsWith(domain))) { 156 this.domain=domainvalue; 157 } else { 158 throw new CookieException("Not allowed to set a cookie for domain " 159 +domainvalue+" from host "+host); 160 } 161 } else if (fieldname.equalsIgnoreCase("jmfdomain")) { 162 String domainvalue = fieldvalue.toLowerCase(); 166 if ((host.equals("")) 168 || (host.endsWith(domain))) { 169 this.domain=domainvalue; 170 } else { 171 throw new CookieException("Not allowed to set a cookie for domain " 172 +domainvalue+" from host "+host); 173 } 174 } else if (fieldname.equalsIgnoreCase("path")) { 175 this.path=fieldvalue; 179 } else if (fieldname.equalsIgnoreCase("secure")) { 180 this.secure = true; 184 } else if (fieldname.equalsIgnoreCase("max-age")) { 185 try { 189 this.maxAge = Integer.parseInt(fieldvalue); 190 } catch (NumberFormatException e) { 191 throw new CookieException("max-age must be integer, but is " 192 +fieldvalue); 193 } 194 195 if (maxAge >= 0) { 196 this.expireDate = new Date (System.currentTimeMillis() 197 +maxAge*1000); 198 } else { 199 this.expireDate = new Date (Long.MAX_VALUE); 200 } 201 } else if (fieldname.equalsIgnoreCase("expires")) { 202 String dateStr = null; 206 java.text.SimpleDateFormat [] df = new java.text.SimpleDateFormat [2]; 207 208 df[0] = new java.text.SimpleDateFormat ("dd-MMM-yyyy HH:mm:ss z", 211 Locale.US); 212 df[1] = new java.text.SimpleDateFormat ("dd MMM yyyy HH:mm:ss z", 213 Locale.US); 214 215 int commapos = fieldvalue.indexOf(","); 216 if (commapos < 0) { 217 throw new CookieException("Expires field does not contain " 218 +"a comma, value is "+fieldvalue); 219 } 220 dateStr = fieldvalue.substring(commapos+1).trim(); 221 boolean foundDate = false; 222 223 for (int i=0; i<df.length; i++) { 224 try { 225 this.expireDate = df[i].parse(dateStr); 226 foundDate=true; 228 continue; 229 } catch (java.text.ParseException e) {}; 230 } 231 232 if (! foundDate) { 234 throw new CookieException("Can't parse expires field as date, " 235 +"value is "+dateStr); 236 } 237 238 } else if (fieldname.equalsIgnoreCase("version")) { 239 try { 243 this.version=Integer.parseInt(fieldvalue); 244 } catch (NumberFormatException e) { 245 throw new CookieException("Version must be integer, but is " 246 +fieldvalue); 247 } 248 249 if (version > 1) { 250 throw new CookieException("Only version 0 and 1 supported yet, " 251 +"but cookie used version "+version); 252 } 253 } 254 } 255 256 } 257 258 263 public Cookie(String name, String value, String domain, String path) { 264 this.name=name; 265 this.value=value; 266 this.domain=domain; 267 this.path=path; 268 } 269 270 271 275 public boolean isValid() { 276 Date current = new Date (); 277 return current.before(expireDate); 278 } 279 280 281 286 public boolean isValid(URL u) { 287 String urlhost = u.getHost().toLowerCase(); 288 String urlpath = u.getPath(); 289 290 return (isValid() 291 && urlhost.endsWith(this.domain) 292 && urlpath.startsWith(path)); 293 } 294 295 301 public boolean overwrites(Cookie c) { 302 return (this.domain.equals(c.domain) 303 && this.path.equals(c.path) 304 && this.name.equals(c.name)); 305 } 306 307 308 312 public String getNameValuePair() { 313 return this.name+"="+this.value; 314 } 315 316 317 322 public String toString() { 323 return this.name+"="+this.value+" (Comment="+this.comment 324 +", Version="+this.version+", domain="+this.domain 325 +", path="+this.path 326 +", expires " 327 +java.text.DateFormat.getDateTimeInstance().format(this.expireDate)+")"; 328 } 329 330 331 333 public static Cookie[] cookieStringToCookies(String cookieStr, String domain) throws CookieException { 334 String cookieHeader; 335 336 if (cookieStr.substring(0,HEADER_COOKIE.length()).equalsIgnoreCase(HEADER_COOKIE)) { 338 cookieHeader = cookieStr.substring(HEADER_COOKIE.length()); 339 } else { 340 throw new CookieException("Not a Cookie header"); 341 } 342 343 StringTokenizer tokens = new StringTokenizer (cookieHeader,";"); 345 Cookie[] cookies= new Cookie[tokens.countTokens()]; 346 int i=0; 347 348 while (tokens.hasMoreTokens()) { 349 cookies[i]=null; 350 String field = tokens.nextToken(); 351 int pos = field.indexOf('='); 352 if (pos <= 0) { 353 throw new CookieException("Cookie field not in the format NAME=VALUE" 354 +" but got "+field); 355 } else { 356 cookies[i]=new Cookie(); 357 cookies[i].name = field.substring(0,pos).trim(); 358 cookies[i].value = field.substring(pos+1); 359 cookies[i].domain = "."+domain; 362 } 363 i++; 364 } 365 366 return cookies; 367 368 } 369 370 371 public boolean isSecure() { 372 return secure; 373 } 374 375 } 376 | Popular Tags |