1 31 32 package org.apache.commons.httpclient.cookie; 33 34 import java.util.Date ; 35 import java.util.LinkedList ; 36 import java.util.List ; 37 38 import org.apache.commons.httpclient.Cookie; 39 import org.apache.commons.httpclient.Header; 40 import org.apache.commons.httpclient.HeaderElement; 41 import org.apache.commons.httpclient.HttpException; 42 import org.apache.commons.httpclient.NameValuePair; 43 import org.apache.commons.httpclient.util.DateParseException; 44 import org.apache.commons.httpclient.util.DateParser; 45 import org.apache.commons.logging.Log; 46 import org.apache.commons.logging.LogFactory; 47 48 65 public class CookieSpecBase implements CookieSpec { 66 67 68 protected static final Log LOG = LogFactory.getLog(CookieSpec.class); 69 70 71 public CookieSpecBase() { 72 super(); 73 } 74 75 76 107 public Cookie[] parse(String host, int port, String path, 108 boolean secure, final String header) 109 throws MalformedCookieException { 110 111 LOG.trace("enter CookieSpecBase.parse(" 112 + "String, port, path, boolean, Header)"); 113 114 if (host == null) { 115 throw new IllegalArgumentException ( 116 "Host of origin may not be null"); 117 } 118 if (host.trim().equals("")) { 119 throw new IllegalArgumentException ( 120 "Host of origin may not be blank"); 121 } 122 if (port < 0) { 123 throw new IllegalArgumentException ("Invalid port: " + port); 124 } 125 if (path == null) { 126 throw new IllegalArgumentException ( 127 "Path of origin may not be null."); 128 } 129 if (header == null) { 130 throw new IllegalArgumentException ("Header may not be null."); 131 } 132 133 if (path.trim().equals("")) { 134 path = PATH_DELIM; 135 } 136 host = host.toLowerCase(); 137 138 HeaderElement[] headerElements = null; 139 try { 140 headerElements = HeaderElement.parse(header); 141 } catch (HttpException e) { 142 throw new MalformedCookieException(e.getMessage()); 143 } 144 145 String defaultPath = path; 146 int lastSlashIndex = defaultPath.lastIndexOf(PATH_DELIM); 147 if (lastSlashIndex >= 0) { 148 if (lastSlashIndex == 0) { 149 lastSlashIndex = 1; 151 } 152 defaultPath = defaultPath.substring(0, lastSlashIndex); 153 } 154 155 Cookie[] cookies = new Cookie[headerElements.length]; 156 157 for (int i = 0; i < headerElements.length; i++) { 158 159 HeaderElement headerelement = headerElements[i]; 160 Cookie cookie = null; 161 try { 162 cookie = new Cookie(host, 163 headerelement.getName(), 164 headerelement.getValue(), 165 defaultPath, 166 null, 167 false); 168 } catch (IllegalArgumentException e) { 169 throw new MalformedCookieException(e.getMessage()); 170 } 171 NameValuePair[] parameters = headerelement.getParameters(); 173 if (parameters != null) { 175 176 for (int j = 0; j < parameters.length; j++) { 177 parseAttribute(parameters[j], cookie); 178 } 179 } 180 cookies[i] = cookie; 181 } 182 return cookies; 183 } 184 185 186 219 public Cookie[] parse( 220 String host, int port, String path, boolean secure, final Header header) 221 throws MalformedCookieException { 222 223 LOG.trace("enter CookieSpecBase.parse(" 224 + "String, port, path, boolean, String)"); 225 if (header == null) { 226 throw new IllegalArgumentException ("Header may not be null."); 227 } 228 return parse(host, port, path, secure, header.getValue()); 229 } 230 231 232 241 242 public void parseAttribute( 243 final NameValuePair attribute, final Cookie cookie) 244 throws MalformedCookieException { 245 246 if (attribute == null) { 247 throw new IllegalArgumentException ("Attribute may not be null."); 248 } 249 if (cookie == null) { 250 throw new IllegalArgumentException ("Cookie may not be null."); 251 } 252 final String paramName = attribute.getName().toLowerCase(); 253 String paramValue = attribute.getValue(); 254 255 if (paramName.equals("path")) { 256 257 if ((paramValue == null) || (paramValue.trim().equals(""))) { 258 paramValue = "/"; 259 } 260 cookie.setPath(paramValue); 261 cookie.setPathAttributeSpecified(true); 262 263 } else if (paramName.equals("domain")) { 264 265 if (paramValue == null) { 266 throw new MalformedCookieException( 267 "Missing value for domain attribute"); 268 } 269 if (paramValue.trim().equals("")) { 270 throw new MalformedCookieException( 271 "Blank value for domain attribute"); 272 } 273 cookie.setDomain(paramValue); 274 cookie.setDomainAttributeSpecified(true); 275 276 } else if (paramName.equals("max-age")) { 277 278 if (paramValue == null) { 279 throw new MalformedCookieException( 280 "Missing value for max-age attribute"); 281 } 282 int age; 283 try { 284 age = Integer.parseInt(paramValue); 285 } catch (NumberFormatException e) { 286 throw new MalformedCookieException ("Invalid max-age " 287 + "attribute: " + e.getMessage()); 288 } 289 cookie.setExpiryDate( 290 new Date (System.currentTimeMillis() + age * 1000L)); 291 292 } else if (paramName.equals("secure")) { 293 294 cookie.setSecure(true); 295 296 } else if (paramName.equals("comment")) { 297 298 cookie.setComment(paramValue); 299 300 } else if (paramName.equals("expires")) { 301 302 if (paramValue == null) { 303 throw new MalformedCookieException( 304 "Missing value for expires attribute"); 305 } 306 if (paramValue.length() > 1 309 && paramValue.startsWith("'") 310 && paramValue.endsWith("'")) { 311 paramValue 312 = paramValue.substring (1, paramValue.length() - 1); 313 } 314 315 try { 316 cookie.setExpiryDate(DateParser.parseDate(paramValue)); 317 } catch (DateParseException dpe) { 318 LOG.debug("Error parsing cookie date", dpe); 319 throw new MalformedCookieException( 320 "Unable to parse expiration date parameter: " 321 + paramValue); 322 } 323 } else { 324 if (LOG.isDebugEnabled()) { 325 LOG.debug("Unrecognized cookie attribute: " 326 + attribute.toString()); 327 } 328 } 329 } 330 331 332 344 345 public void validate(String host, int port, String path, 346 boolean secure, final Cookie cookie) 347 throws MalformedCookieException { 348 349 LOG.trace("enter CookieSpecBase.validate(" 350 + "String, port, path, boolean, Cookie)"); 351 if (host == null) { 352 throw new IllegalArgumentException ( 353 "Host of origin may not be null"); 354 } 355 if (host.trim().equals("")) { 356 throw new IllegalArgumentException ( 357 "Host of origin may not be blank"); 358 } 359 if (port < 0) { 360 throw new IllegalArgumentException ("Invalid port: " + port); 361 } 362 if (path == null) { 363 throw new IllegalArgumentException ( 364 "Path of origin may not be null."); 365 } 366 if (path.trim().equals("")) { 367 path = PATH_DELIM; 368 } 369 host = host.toLowerCase(); 370 if (cookie.getVersion() < 0) { 372 throw new MalformedCookieException ("Illegal version number " 373 + cookie.getValue()); 374 } 375 376 379 if (host.indexOf(".") >= 0) { 385 388 if (!host.endsWith(cookie.getDomain())) { 390 String s = cookie.getDomain(); 391 if (s.startsWith(".")) { 392 s = s.substring(1, s.length()); 393 } 394 if (!host.equals(s)) { 395 throw new MalformedCookieException( 396 "Illegal domain attribute \"" + cookie.getDomain() 397 + "\". Domain of origin: \"" + host + "\""); 398 } 399 } 400 } else { 401 if (!host.equals(cookie.getDomain())) { 402 throw new MalformedCookieException( 403 "Illegal domain attribute \"" + cookie.getDomain() 404 + "\". Domain of origin: \"" + host + "\""); 405 } 406 } 407 408 411 if (!path.startsWith(cookie.getPath())) { 412 throw new MalformedCookieException( 413 "Illegal path attribute \"" + cookie.getPath() 414 + "\". Path of origin: \"" + path + "\""); 415 } 416 } 417 418 419 429 430 public boolean match(String host, int port, String path, 431 boolean secure, final Cookie cookie) { 432 433 LOG.trace("enter CookieSpecBase.match(" 434 + "String, int, String, boolean, Cookie"); 435 436 if (host == null) { 437 throw new IllegalArgumentException ( 438 "Host of origin may not be null"); 439 } 440 if (host.trim().equals("")) { 441 throw new IllegalArgumentException ( 442 "Host of origin may not be blank"); 443 } 444 if (port < 0) { 445 throw new IllegalArgumentException ("Invalid port: " + port); 446 } 447 if (path == null) { 448 throw new IllegalArgumentException ( 449 "Path of origin may not be null."); 450 } 451 if (cookie == null) { 452 throw new IllegalArgumentException ("Cookie may not be null"); 453 } 454 if (path.trim().equals("")) { 455 path = PATH_DELIM; 456 } 457 host = host.toLowerCase(); 458 if (cookie.getDomain() == null) { 459 LOG.warn("Invalid cookie state: domain not specified"); 460 return false; 461 } 462 if (cookie.getPath() == null) { 463 LOG.warn("Invalid cookie state: path not specified"); 464 return false; 465 } 466 467 return 468 (cookie.getExpiryDate() == null 470 || cookie.getExpiryDate().after(new Date ())) 471 && (domainMatch(host, cookie.getDomain())) 473 && (pathMatch(path, cookie.getPath())) 475 && (cookie.getSecure() ? secure : true); 478 } 479 480 486 private static boolean domainMatch(String host, String domain) { 487 boolean match = host.equals(domain) 488 || (domain.startsWith(".") && host.endsWith(domain)); 489 490 return match; 491 } 492 493 500 private static boolean pathMatch( 501 final String path, final String topmostPath) { 502 503 boolean match = path.startsWith (topmostPath); 504 505 if (match && path.length() != topmostPath.length()) { 508 if (!topmostPath.endsWith(PATH_DELIM)) { 509 match = (path.charAt(topmostPath.length()) == PATH_DELIM_CHAR); 510 } 511 } 512 return match; 513 } 514 515 526 527 public Cookie[] match(String host, int port, String path, 528 boolean secure, final Cookie cookies[]) { 529 530 LOG.trace("enter CookieSpecBase.match(" 531 + "String, int, String, boolean, Cookie[])"); 532 533 if (host == null) { 534 throw new IllegalArgumentException ( 535 "Host of origin may not be null"); 536 } 537 if (host.trim().equals("")) { 538 throw new IllegalArgumentException ( 539 "Host of origin may not be blank"); 540 } 541 if (port < 0) { 542 throw new IllegalArgumentException ("Invalid port: " + port); 543 } 544 if (path == null) { 545 throw new IllegalArgumentException ( 546 "Path of origin may not be null."); 547 } 548 if (cookies == null) { 549 throw new IllegalArgumentException ("Cookie array may not be null"); 550 } 551 if (path.trim().equals("")) { 552 path = PATH_DELIM; 553 } 554 host = host.toLowerCase(); 555 556 if (cookies.length <= 0) { 557 return null; 558 } 559 List matching = new LinkedList (); 560 for (int i = 0; i < cookies.length; i++) { 561 if (match(host, port, path, secure, cookies[i])) { 562 addInPathOrder(matching, cookies[i]); 563 } 564 } 565 return (Cookie[]) matching.toArray(new Cookie[matching.size()]); 566 } 567 568 569 578 private static void addInPathOrder(List list, Cookie addCookie) { 579 int i = 0; 580 581 for (i = 0; i < list.size(); i++) { 582 Cookie c = (Cookie) list.get(i); 583 if (addCookie.compare(addCookie, c) > 0) { 584 break; 585 } 586 } 587 list.add(i, addCookie); 588 } 589 590 595 public String formatCookie(Cookie cookie) { 596 LOG.trace("enter CookieSpecBase.formatCookie(Cookie)"); 597 if (cookie == null) { 598 throw new IllegalArgumentException ("Cookie may not be null"); 599 } 600 StringBuffer buf = new StringBuffer (); 601 buf.append(cookie.getName()); 602 buf.append("="); 603 String s = cookie.getValue(); 604 if (s != null) { 605 buf.append(s); 606 }; 607 return buf.toString(); 608 } 609 610 617 618 public String formatCookies(Cookie[] cookies) 619 throws IllegalArgumentException { 620 LOG.trace("enter CookieSpecBase.formatCookies(Cookie[])"); 621 if (cookies == null) { 622 throw new IllegalArgumentException ("Cookie array may not be null"); 623 } 624 if (cookies.length == 0) { 625 throw new IllegalArgumentException ("Cookie array may not be empty"); 626 } 627 628 StringBuffer buffer = new StringBuffer (); 629 for (int i = 0; i < cookies.length; i++) { 630 if (i > 0) { 631 buffer.append("; "); 632 } 633 buffer.append(formatCookie(cookies[i])); 634 } 635 return buffer.toString(); 636 } 637 638 639 646 public Header formatCookieHeader(Cookie[] cookies) { 647 LOG.trace("enter CookieSpecBase.formatCookieHeader(Cookie[])"); 648 return new Header("Cookie", formatCookies(cookies)); 649 } 650 651 652 658 public Header formatCookieHeader(Cookie cookie) { 659 LOG.trace("enter CookieSpecBase.formatCookieHeader(Cookie)"); 660 return new Header("Cookie", formatCookie(cookie)); 661 } 662 663 } 664 | Popular Tags |