1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.apache.commons.httpclient;
33
34 import java.io.Serializable;
35 import java.text.RuleBasedCollator;
36 import java.util.Comparator;
37 import java.util.Date;
38 import java.util.Locale;
39
40 import org.apache.commons.httpclient.cookie.CookiePolicy;
41 import org.apache.commons.httpclient.cookie.CookieSpec;
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44
45
46 /***
47 * <p>
48 * HTTP "magic-cookie" represents a piece of state information
49 * that the HTTP agent and the target server can exchange to maintain
50 * a session.
51 * </p>
52 *
53 * @author B.C. Holmes
54 * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
55 * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
56 * @author Rod Waldhoff
57 * @author dIon Gillard
58 * @author Sean C. Sullivan
59 * @author <a href="mailto:JEvans@Cyveillance.com">John Evans</a>
60 * @author Marc A. Saegesser
61 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
62 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
63 *
64 * @version $Revision: 1.38.2.4 $ $Date: 2004/06/05 16:32:01 $
65 */
66
67 public class Cookie extends NameValuePair implements Serializable, Comparator {
68
69
70
71 /***
72 * Default constructor. Creates a blank cookie
73 */
74
75 public Cookie() {
76 this(null, "noname", null, null, null, false);
77 }
78
79 /***
80 * Creates a cookie with the given name, value and domain attribute.
81 *
82 * @param name the cookie name
83 * @param value the cookie value
84 * @param domain the domain this cookie can be sent to
85 */
86 public Cookie(String domain, String name, String value) {
87 this(domain, name, value, null, null, false);
88 }
89
90 /***
91 * Creates a cookie with the given name, value, domain attribute,
92 * path attribute, expiration attribute, and secure attribute
93 *
94 * @param name the cookie name
95 * @param value the cookie value
96 * @param domain the domain this cookie can be sent to
97 * @param path the path prefix for which this cookie can be sent
98 * @param expires the {@link Date} at which this cookie expires,
99 * or <tt>null</tt> if the cookie expires at the end
100 * of the session
101 * @param secure if true this cookie can only be sent over secure
102 * connections
103 * @throws IllegalArgumentException If cookie name is null or blank,
104 * cookie name contains a blank, or cookie name starts with character $
105 *
106 */
107 public Cookie(String domain, String name, String value,
108 String path, Date expires, boolean secure) {
109
110 super(name, value);
111 LOG.trace("enter Cookie(String, String, String, String, Date, boolean)");
112 if (name == null) {
113 throw new IllegalArgumentException("Cookie name may not be null");
114 }
115 if (name.trim().equals("")) {
116 throw new IllegalArgumentException("Cookie name may not be blank");
117 }
118 this.setPath(path);
119 this.setDomain(domain);
120 this.setExpiryDate(expires);
121 this.setSecure(secure);
122 }
123
124 /***
125 * Creates a cookie with the given name, value, domain attribute,
126 * path attribute, maximum age attribute, and secure attribute
127 *
128 * @param name the cookie name
129 * @param value the cookie value
130 * @param domain the domain this cookie can be sent to
131 * @param path the path prefix for which this cookie can be sent
132 * @param maxAge the number of seconds for which this cookie is valid.
133 * maxAge is expected to be a non-negative number.
134 * <tt>-1</tt> signifies that the cookie should never expire.
135 * @param secure if <tt>true</tt> this cookie can only be sent over secure
136 * connections
137 */
138 public Cookie(String domain, String name, String value, String path,
139 int maxAge, boolean secure) {
140
141 this(domain, name, value, path, null, secure);
142 if (maxAge < -1) {
143 throw new IllegalArgumentException("Invalid max age: " + Integer.toString(maxAge));
144 }
145 if (maxAge >= 0) {
146 setExpiryDate(new Date(System.currentTimeMillis() + maxAge * 1000L));
147 }
148 }
149
150 /***
151 * Returns the comment describing the purpose of this cookie, or
152 * <tt>null</tt> if no such comment has been defined.
153 *
154 * @return comment
155 *
156 * @see #setComment(String)
157 */
158 public String getComment() {
159 return cookieComment;
160 }
161
162 /***
163 * If a user agent (web browser) presents this cookie to a user, the
164 * cookie's purpose will be described using this comment.
165 *
166 * @param comment
167 *
168 * @see #getComment()
169 */
170 public void setComment(String comment) {
171 cookieComment = comment;
172 }
173
174 /***
175 * Returns the expiration {@link Date} of the cookie, or <tt>null</tt>
176 * if none exists.
177 * <p><strong>Note:</strong> the object returned by this method is
178 * considered immutable. Changing it (e.g. using setTime()) could result
179 * in undefined behaviour. Do so at your peril. </p>
180 * @return Expiration {@link Date}, or <tt>null</tt>.
181 *
182 * @see #setExpiryDate(java.util.Date)
183 *
184 */
185 public Date getExpiryDate() {
186 return cookieExpiryDate;
187 }
188
189 /***
190 * Sets expiration date.
191 * <p><strong>Note:</strong> the object returned by this method is considered
192 * immutable. Changing it (e.g. using setTime()) could result in undefined
193 * behaviour. Do so at your peril.</p>
194 *
195 * @param expiryDate the {@link Date} after which this cookie is no longer valid.
196 *
197 * @see #getExpiryDate
198 *
199 */
200 public void setExpiryDate (Date expiryDate) {
201 cookieExpiryDate = expiryDate;
202 }
203
204
205 /***
206 * Returns <tt>false</tt> if the cookie should be discarded at the end
207 * of the "session"; <tt>true</tt> otherwise.
208 *
209 * @return <tt>false</tt> if the cookie should be discarded at the end
210 * of the "session"; <tt>true</tt> otherwise
211 */
212 public boolean isPersistent() {
213 return (null != cookieExpiryDate);
214 }
215
216
217 /***
218 * Returns domain attribute of the cookie.
219 *
220 * @return the value of the domain attribute
221 *
222 * @see #setDomain(java.lang.String)
223 */
224 public String getDomain() {
225 return cookieDomain;
226 }
227
228 /***
229 * Sets the domain attribute.
230 *
231 * @param domain The value of the domain attribute
232 *
233 * @see #getDomain
234 */
235 public void setDomain(String domain) {
236 if (domain != null) {
237 int ndx = domain.indexOf(":");
238 if (ndx != -1) {
239 domain = domain.substring(0, ndx);
240 }
241 cookieDomain = domain.toLowerCase();
242 }
243 }
244
245
246 /***
247 * Returns the path attribute of the cookie
248 *
249 * @return The value of the path attribute.
250 *
251 * @see #setPath(java.lang.String)
252 */
253 public String getPath() {
254 return cookiePath;
255 }
256
257 /***
258 * Sets the path attribute.
259 *
260 * @param path The value of the path attribute
261 *
262 * @see #getPath
263 *
264 */
265 public void setPath(String path) {
266 cookiePath = path;
267 }
268
269 /***
270 * @return <code>true</code> if this cookie should only be sent over secure connections.
271 * @see #setSecure(boolean)
272 */
273 public boolean getSecure() {
274 return isSecure;
275 }
276
277 /***
278 * Sets the secure attribute of the cookie.
279 * <p>
280 * When <tt>true</tt> the cookie should only be sent
281 * using a secure protocol (https). This should only be set when
282 * the cookie's originating server used a secure protocol to set the
283 * cookie's value.
284 *
285 * @param secure The value of the secure attribute
286 *
287 * @see #getSecure()
288 */
289 public void setSecure (boolean secure) {
290 isSecure = secure;
291 }
292
293 /***
294 * Returns the version of the cookie specification to which this
295 * cookie conforms.
296 *
297 * @return the version of the cookie.
298 *
299 * @see #setVersion(int)
300 *
301 */
302 public int getVersion() {
303 return cookieVersion;
304 }
305
306 /***
307 * Sets the version of the cookie specification to which this
308 * cookie conforms.
309 *
310 * @param version the version of the cookie.
311 *
312 * @see #getVersion
313 */
314 public void setVersion(int version) {
315 cookieVersion = version;
316 }
317
318 /***
319 * Returns true if this cookie has expired.
320 *
321 * @return <tt>true</tt> if the cookie has expired.
322 */
323 public boolean isExpired() {
324 return (cookieExpiryDate != null
325 && cookieExpiryDate.getTime() <= System.currentTimeMillis());
326 }
327
328 /***
329 * Returns true if this cookie has expired according to the time passed in.
330 *
331 * @param now The current time.
332 *
333 * @return <tt>true</tt> if the cookie expired.
334 */
335 public boolean isExpired(Date now) {
336 return (cookieExpiryDate != null
337 && cookieExpiryDate.getTime() <= now.getTime());
338 }
339
340
341 /***
342 * Indicates whether the cookie had a path specified in a
343 * path attribute of the <tt>Set-Cookie</tt> header. This value
344 * is important for generating the <tt>Cookie</tt> header because
345 * some cookie specifications require that the <tt>Cookie</tt> header
346 * should only include a path attribute if the cookie's path
347 * was specified in the <tt>Set-Cookie</tt> header.
348 *
349 * @param value <tt>true</tt> if the cookie's path was explicitly
350 * set, <tt>false</tt> otherwise.
351 *
352 * @see #isPathAttributeSpecified
353 */
354 public void setPathAttributeSpecified(boolean value) {
355 hasPathAttribute = value;
356 }
357
358 /***
359 * Returns <tt>true</tt> if cookie's path was set via a path attribute
360 * in the <tt>Set-Cookie</tt> header.
361 *
362 * @return value <tt>true</tt> if the cookie's path was explicitly
363 * set, <tt>false</tt> otherwise.
364 *
365 * @see #setPathAttributeSpecified
366 */
367 public boolean isPathAttributeSpecified() {
368 return hasPathAttribute;
369 }
370
371 /***
372 * Indicates whether the cookie had a domain specified in a
373 * domain attribute of the <tt>Set-Cookie</tt> header. This value
374 * is important for generating the <tt>Cookie</tt> header because
375 * some cookie specifications require that the <tt>Cookie</tt> header
376 * should only include a domain attribute if the cookie's domain
377 * was specified in the <tt>Set-Cookie</tt> header.
378 *
379 * @param value <tt>true</tt> if the cookie's domain was explicitly
380 * set, <tt>false</tt> otherwise.
381 *
382 * @see #isDomainAttributeSpecified
383 */
384 public void setDomainAttributeSpecified(boolean value) {
385 hasDomainAttribute = value;
386 }
387
388 /***
389 * Returns <tt>true</tt> if cookie's domain was set via a domain
390 * attribute in the <tt>Set-Cookie</tt> header.
391 *
392 * @return value <tt>true</tt> if the cookie's domain was explicitly
393 * set, <tt>false</tt> otherwise.
394 *
395 * @see #setDomainAttributeSpecified
396 */
397 public boolean isDomainAttributeSpecified() {
398 return hasDomainAttribute;
399 }
400
401 /***
402 * Returns a hash code in keeping with the
403 * {@link Object#hashCode} general hashCode contract.
404 * @return A hash code
405 */
406 public int hashCode() {
407 return super.hashCode()
408 ^ (null == cookiePath ? 0 : cookiePath.hashCode())
409 ^ (null == cookieDomain ? 0 : cookieDomain.hashCode());
410 }
411
412
413 /***
414 * Two cookies are equal if the name, path and domain match.
415 * @param obj The object to compare against.
416 * @return true if the two objects are equal.
417 */
418 public boolean equals(Object obj) {
419 LOG.trace("enter Cookie.equals(Object)");
420
421 if ((obj != null) && (obj instanceof Cookie)) {
422 Cookie that = (Cookie) obj;
423 return
424 (null == this.getName()
425 ? null == that.getName()
426 : this.getName().equals(that.getName()))
427 && (null == this.getPath()
428 ? null == that.getPath()
429 : this.getPath().equals(that.getPath()))
430 && (null == this.getDomain()
431 ? null == that.getDomain()
432 : this.getDomain().equals(that.getDomain()));
433 } else {
434 return false;
435 }
436 }
437
438
439 /***
440 * Returns a textual representation of the cookie.
441 *
442 * @return string .
443 */
444 public String toExternalForm() {
445 return CookiePolicy.getSpecByVersion(
446 getVersion()).formatCookie(this);
447 }
448
449 /***
450 * Return <tt>true</tt> if I should be submitted with a request with given
451 * attributes, <tt>false</tt> otherwise.
452 * @param domain the host to which the request is being submitted
453 * @param port the port to which the request is being submitted (currently
454 * ignored)
455 * @param path the path to which the request is being submitted
456 * @param secure <tt>true</tt> if the request is using the HTTPS protocol
457 * @param date the time at which the request is submitted
458 * @return true if the cookie matches
459 *
460 * @deprecated use {@link CookieSpec} interface
461 */
462 public boolean matches(
463 String domain, int port, String path, boolean secure, Date date) {
464
465 LOG.trace("enter Cookie.matches(Strinng, int, String, boolean, Date");
466 CookieSpec matcher = CookiePolicy.getDefaultSpec();
467 return matcher.match(domain, port, path, secure, this);
468 }
469
470 /***
471 * Return <tt>true</tt> if I should be submitted with a request with given
472 * attributes, <tt>false</tt> otherwise.
473 * @param domain the host to which the request is being submitted
474 * @param port the port to which the request is being submitted (currently
475 * ignored)
476 * @param path the path to which the request is being submitted
477 * @param secure True if this cookie has the secure flag set
478 * @return true if I should be submitted as above.
479 * @deprecated use {@link CookieSpec} interface
480 */
481 public boolean matches(
482 String domain, int port, String path, boolean secure) {
483 LOG.trace("enter Cookie.matches(String, int, String, boolean");
484 return matches(domain, port, path, secure, new Date());
485 }
486
487 /***
488 * Create a <tt>Cookie</tt> header containing
489 * all non-expired cookies in <i>cookies</i>,
490 * associated with the given <i>domain</i> and
491 * <i>path</i>, assuming the connection is not
492 * secure.
493 * <p>
494 * If no cookies match, returns null.
495 *
496 * @param domain The domain
497 * @param path The path
498 * @param cookies The cookies to use
499 * @return The new header.
500 * @deprecated use {@link CookieSpec} interface
501 */
502 public static Header createCookieHeader(String domain, String path,
503 Cookie[] cookies) {
504
505 LOG.trace("enter Cookie.createCookieHeader(String,String,Cookie[])");
506 return Cookie.createCookieHeader(domain, path, false, cookies);
507 }
508
509 /***
510 * Create a <tt>Cookie</tt> header containing
511 * all non-expired cookies in <i>cookies</i>,
512 * associated with the given <i>domain</i>, <i>path</i> and
513 * <i>https</i> setting.
514 * <p>
515 * If no cookies match, returns null.
516 *
517 * @param domain The domain
518 * @param path The path
519 * @param secure True if this cookie has the secure flag set
520 * @param cookies The cookies to use.
521 * @return The new header
522 * @exception IllegalArgumentException if domain or path is null
523 *
524 * @deprecated use {@link CookieSpec} interface
525 */
526 public static Header createCookieHeader(String domain, String path,
527 boolean secure, Cookie[] cookies)
528 throws IllegalArgumentException {
529
530 LOG.trace("enter Cookie.createCookieHeader("
531 + "String, String, boolean, Cookie[])");
532
533
534
535 if (domain == null) {
536 throw new IllegalArgumentException("null domain in "
537 + "createCookieHeader.");
538 }
539
540 int port = secure ? 443 : 80;
541 int ndx = domain.indexOf(":");
542 if (ndx != -1) {
543 try {
544 port = Integer.parseInt(domain.substring(ndx + 1,
545 domain.length()));
546 } catch (NumberFormatException e) {
547
548 LOG.warn("Cookie.createCookieHeader(): "
549 + "Invalid port number in domain " + domain);
550 }
551 }
552 return Cookie.createCookieHeader(domain, port, path, secure, cookies);
553 }
554
555 /***
556 * Create a <tt>Cookie</tt> header containing
557 * all non-expired cookies in <i>cookies</i>,
558 * associated with the given <i>domain</i>, <i>port</i>,
559 * <i>path</i> and <i>https</i> setting.
560 * <p>
561 * If no cookies match, returns null.
562 *
563 * @param domain The domain
564 * @param port The port
565 * @param path The path
566 * @param secure True if this cookie has the secure flag set
567 * @param cookies The cookies to use.
568 * @return The new header
569 * @throws IllegalArgumentException if domain or path is null
570 *
571 * @deprecated use {@link CookieSpec} interface
572 */
573 public static Header createCookieHeader(String domain, int port,
574 String path, boolean secure, Cookie[] cookies)
575 throws IllegalArgumentException {
576 LOG.trace("enter Cookie.createCookieHeader(String, int, String, boolean, Cookie[])");
577 return Cookie.createCookieHeader(domain, port, path, secure, new Date(), cookies);
578 }
579
580 /***
581 * Create a <tt>Cookie</tt> header containing all cookies in <i>cookies</i>,
582 * associated with the given <i>domain</i>, <i>port</i>, <i>path</i> and
583 * <i>https</i> setting, and which are not expired according to the given
584 * <i>date</i>.
585 * <p>
586 * If no cookies match, returns null.
587 *
588 * @param domain The domain
589 * @param port The port
590 * @param path The path
591 * @param secure True if this cookie has the secure flag set
592 * @param now The date to check for expiry
593 * @param cookies The cookies to use.
594 * @return The new header
595 * @throws IllegalArgumentException if domain or path is null
596 *
597 * @deprecated use {@link CookieSpec} interface
598 */
599
600 public static Header createCookieHeader(
601 String domain, int port, String path, boolean secure,
602 Date now, Cookie[] cookies)
603 throws IllegalArgumentException {
604
605 LOG.trace("enter Cookie.createCookieHeader(String, int, String, boolean, Date, Cookie[])");
606 CookieSpec matcher = CookiePolicy.getDefaultSpec();
607 cookies = matcher.match(domain, port, path, secure, cookies);
608 if ((cookies != null) && (cookies.length > 0)) {
609 return matcher.formatCookieHeader(cookies);
610 } else {
611 return null;
612 }
613 }
614
615 /***
616 * <p>Compares two cookies to determine order for cookie header.</p>
617 * <p>Most specific should be first. </p>
618 * <p>This method is implemented so a cookie can be used as a comparator for
619 * a SortedSet of cookies. Specifically it's used above in the
620 * createCookieHeader method.</p>
621 * @param o1 The first object to be compared
622 * @param o2 The second object to be compared
623 * @return See {@link java.util.Comparator#compare(Object,Object)}
624 */
625 public int compare(Object o1, Object o2) {
626 LOG.trace("enter Cookie.compare(Object, Object)");
627
628 if (!(o1 instanceof Cookie)) {
629 throw new ClassCastException(o1.getClass().getName());
630 }
631 if (!(o2 instanceof Cookie)) {
632 throw new ClassCastException(o2.getClass().getName());
633 }
634 Cookie c1 = (Cookie) o1;
635 Cookie c2 = (Cookie) o2;
636 if (c1.getPath() == null && c2.getPath() == null) {
637 return 0;
638 } else if (c1.getPath() == null) {
639
640 if (c2.getPath().equals(CookieSpec.PATH_DELIM)) {
641 return 0;
642 } else {
643 return -1;
644 }
645 } else if (c2.getPath() == null) {
646
647 if (c1.getPath().equals(CookieSpec.PATH_DELIM)) {
648 return 0;
649 } else {
650 return 1;
651 }
652 } else {
653 return STRING_COLLATOR.compare(c1.getPath(), c2.getPath());
654 }
655 }
656
657 /***
658 * Return a textual representation of the cookie.
659 * @see #toExternalForm
660 */
661 public String toString() {
662 return toExternalForm();
663 }
664
665 /***
666 * Parses the Set-Cookie {@link Header} into an array of
667 * <tt>Cookie</tt>s, assuming that the cookies were recieved
668 * on an insecure channel.
669 *
670 * @param domain the domain from which the {@link Header} was received
671 * @param port the port from which the {@link Header} was received
672 * (currently ignored)
673 * @param path the path from which the {@link Header} was received
674 * @param setCookie the <tt>Set-Cookie</tt> {@link Header} received from the
675 * server
676 * @return an array of <tt>Cookie</tt>s parsed from the Set-Cookie {@link
677 * Header}
678 * @throws HttpException if an exception occurs during parsing
679 * @throws IllegalArgumentException if domain or path are null
680 *
681 * @deprecated use {@link CookieSpec} interface
682 */
683 public static Cookie[] parse(
684 String domain, int port, String path, Header setCookie)
685 throws HttpException, IllegalArgumentException {
686
687 LOG.trace("enter Cookie.parse(String, int, String, Header)");
688 return Cookie.parse(domain, port, path, false, setCookie);
689 }
690
691 /***
692 * Parses the Set-Cookie {@link Header} into an array of
693 * <tt>Cookie</tt>s, assuming that the cookies were recieved
694 * on an insecure channel.
695 *
696 * @param domain the domain from which the {@link Header} was received
697 * @param path the path from which the {@link Header} was received
698 * @param setCookie the <tt>Set-Cookie</tt> {@link Header} received from the
699 * server
700 * @return an array of <tt>Cookie</tt>s parsed from the Set-Cookie {@link
701 * Header}
702 * @throws HttpException if an exception occurs during parsing
703 * @throws IllegalArgumentException if domain or path are null
704 *
705 * @deprecated use {@link CookieSpec} interface
706 */
707 public static Cookie[] parse(String domain, String path, Header setCookie)
708 throws HttpException, IllegalArgumentException {
709 LOG.trace("enter Cookie.parse(String, String, Header)");
710 return Cookie.parse (domain, 80, path, false, setCookie);
711 }
712
713 /***
714 * Parses the Set-Cookie {@link Header} into an array of
715 * <tt>Cookie</tt>s.
716 *
717 * @param domain the domain from which the {@link Header} was received
718 * @param path the path from which the {@link Header} was received
719 * @param secure <tt>true</tt> when the header was recieved over a secure
720 * channel
721 * @param setCookie the <tt>Set-Cookie</tt> {@link Header} received from the
722 * server
723 * @return an array of <tt>Cookie</tt>s parsed from the Set-Cookie {@link
724 * Header}
725 * @throws HttpException if an exception occurs during parsing
726 * @throws IllegalArgumentException if domain or path are null
727 *
728 * @deprecated use {@link CookieSpec} interface
729 */
730 public static Cookie[] parse(String domain, String path,
731 boolean secure, Header setCookie)
732 throws HttpException, IllegalArgumentException {
733
734 LOG.trace ("enter Cookie.parse(String, String, boolean, Header)");
735 return Cookie.parse (
736 domain, (secure ? 443 : 80), path, secure, setCookie);
737 }
738
739 /***
740 * Parses the Set-Cookie {@link Header} into an array of
741 * <tt>Cookie</tt>s.
742 *
743 * <P>The syntax for the Set-Cookie response header is:
744 *
745 * <PRE>
746 * set-cookie = "Set-Cookie:" cookies
747 * cookies = 1#cookie
748 * cookie = NAME "=" VALUE * (";" cookie-av)
749 * NAME = attr
750 * VALUE = value
751 * cookie-av = "Comment" "=" value
752 * | "Domain" "=" value
753 * | "Max-Age" "=" value
754 * | "Path" "=" value
755 * | "Secure"
756 * | "Version" "=" 1*DIGIT
757 * </PRE>
758 *
759 * @param domain the domain from which the {@link Header} was received
760 * @param port The port from which the {@link Header} was received.
761 * @param path the path from which the {@link Header} was received
762 * @param secure <tt>true</tt> when the {@link Header} was received over
763 * HTTPS
764 * @param setCookie the <tt>Set-Cookie</tt> {@link Header} received from
765 * the server
766 * @return an array of <tt>Cookie</tt>s parsed from the Set-Cookie {@link
767 * Header}
768 * @throws HttpException if an exception occurs during parsing
769 *
770 * @deprecated use {@link CookieSpec} interface
771 */
772 public static Cookie[] parse(String domain, int port, String path,
773 boolean secure, Header setCookie)
774 throws HttpException {
775
776 LOG.trace("enter Cookie.parse(String, int, String, boolean, Header)");
777
778 CookieSpec parser = CookiePolicy.getDefaultSpec();
779 Cookie[] cookies = parser.parse(domain, port, path, secure, setCookie);
780
781 for (int i = 0; i < cookies.length; i++) {
782 final Cookie cookie = cookies[i];
783 final CookieSpec validator
784 = CookiePolicy.getSpecByVersion(cookie.getVersion());
785 validator.validate(domain, port, path, secure, cookie);
786 }
787 return cookies;
788 }
789
790
791
792 /*** Comment attribute. */
793 private String cookieComment;
794
795 /*** Domain attribute. */
796 private String cookieDomain;
797
798 /*** Expiration {@link Date}. */
799 private Date cookieExpiryDate;
800
801 /*** Path attribute. */
802 private String cookiePath;
803
804 /*** My secure flag. */
805 private boolean isSecure;
806
807 /***
808 * Specifies if the set-cookie header included a Path attribute for this
809 * cookie
810 */
811 private boolean hasPathAttribute = false;
812
813 /***
814 * Specifies if the set-cookie header included a Domain attribute for this
815 * cookie
816 */
817 private boolean hasDomainAttribute = false;
818
819 /*** The version of the cookie specification I was created from. */
820 private int cookieVersion = 0;
821
822
823
824 /***
825 * Collator for Cookie comparisons. Could be replaced with references to
826 * specific Locales.
827 */
828 private static final RuleBasedCollator STRING_COLLATOR =
829 (RuleBasedCollator) RuleBasedCollator.getInstance(
830 new Locale("en", "US", ""));
831
832 /*** Log object for this class */
833 private static final Log LOG = LogFactory.getLog(Cookie.class);
834
835 }
836