1 /*
2 * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/Cookie.java,v 1.38.2.1 2003/07/07 19:11:00 olegk Exp $
3 * $Revision: 1.38.2.1 $
4 * $Date: 2003/07/07 19:11:00 $
5 *
6 * ====================================================================
7 *
8 * The Apache Software License, Version 1.1
9 *
10 * Copyright (c) 1999-2003 The Apache Software Foundation. All rights
11 * reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in
22 * the documentation and/or other materials provided with the
23 * distribution.
24 *
25 * 3. The end-user documentation included with the redistribution, if
26 * any, must include the following acknowlegement:
27 * "This product includes software developed by the
28 * Apache Software Foundation (http://www.apache.org/)."
29 * Alternately, this acknowlegement may appear in the software itself,
30 * if and wherever such third-party acknowlegements normally appear.
31 *
32 * 4. The names "The Jakarta Project", "Commons", and "Apache Software
33 * Foundation" must not be used to endorse or promote products derived
34 * from this software without prior written permission. For written
35 * permission, please contact apache@apache.org.
36 *
37 * 5. Products derived from this software may not be called "Apache"
38 * nor may "Apache" appear in their names without prior written
39 * permission of the Apache Group.
40 *
41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 * SUCH DAMAGE.
53 * ====================================================================
54 *
55 * This software consists of voluntary contributions made by many
56 * individuals on behalf of the Apache Software Foundation. For more
57 * information on the Apache Software Foundation, please see
58 * <http://www.apache.org/>.
59 *
60 * [Additional notices, if required by prior licensing conditions]
61 *
62 */
63
64 package org.apache.commons.httpclient;
65
66 import java.io.Serializable;
67 import java.text.RuleBasedCollator;
68 import java.util.Comparator;
69 import java.util.Date;
70 import java.util.Locale;
71
72 import org.apache.commons.httpclient.cookie.CookiePolicy;
73 import org.apache.commons.httpclient.cookie.CookieSpec;
74 import org.apache.commons.logging.Log;
75 import org.apache.commons.logging.LogFactory;
76
77
78 /***
79 * <p>An HTTP "magic-cookie", as specified in RFC 2109.</p>
80 *
81 * @author B.C. Holmes
82 * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
83 * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
84 * @author Rod Waldhoff
85 * @author dIon Gillard
86 * @author Sean C. Sullivan
87 * @author <a href="mailto:JEvans@Cyveillance.com">John Evans</a>
88 * @author Marc A. Saegesser
89 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
90 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
91 *
92 * @version $Revision: 1.38.2.1 $ $Date: 2003/07/07 19:11:00 $
93 */
94
95 public class Cookie extends NameValuePair implements Serializable, Comparator {
96
97 // ----------------------------------------------------------- Constructors
98
99 /***
100 * Create a cookie. Default constructor
101 *
102 * The new cookie is assigned
103 */
104
105 public Cookie() {
106 this(null, "noname", null, null, null, false);
107 }
108
109 /***
110 * Create a cookie.
111 *
112 * @param name the cookie name
113 * @param value the cookie value
114 * @param domain the host this cookie will be sent to
115 */
116 public Cookie(String domain, String name, String value) {
117 this(domain, name, value, null, null, false);
118 }
119
120 /***
121 * Create a cookie.
122 *
123 * @param name the cookie name
124 * @param value the cookie value
125 * @param domain the host this cookie will be sent to
126 * @param path the path prefix for which this cookie will be sent
127 * @param expires the {@link Date} at which this cookie expires,
128 * or <tt>null</tt> if the cookie expires at the end
129 * of the session
130 * @param secure if true this cookie will only be sent over secure
131 * connections
132 */
133 public Cookie(String domain, String name, String value,
134 String path, Date expires, boolean secure) {
135
136 super(name, value);
137 LOG.trace("enter Cookie(String, String, String, String, Date, boolean)");
138 if (name == null) {
139 throw new IllegalArgumentException("Cookie name may not be null");
140 }
141 if (name.equals("")) {
142 throw new IllegalArgumentException("Cookie name may not be blank");
143 }
144 if (name.indexOf(' ') != -1) {
145 throw new IllegalArgumentException("Cookie name may not contain blanks");
146 }
147 if (name.startsWith("$")) {
148 throw new IllegalArgumentException("Cookie name may not start with $");
149 }
150 this.setPath(path);
151 this.setDomain(domain);
152 this.setExpiryDate(expires);
153 this.setSecure(secure);
154 }
155
156 /***
157 * Create a cookie.
158 *
159 * @param name the cookie name
160 * @param value the cookie value
161 * @param domain the host this cookie will be sent to
162 * @param path the path prefix for which this cookie will be sent
163 * @param maxAge the number of seconds for which this cookie is valid.
164 * maxAge is expected to be a non-negative number.
165 * <tt>-1</tt> signifies that the cookie should never expire.
166 * @param secure if <tt>true</tt> this cookie will only be sent over secure
167 * connections
168 */
169 public Cookie(String domain, String name, String value, String path,
170 int maxAge, boolean secure) {
171
172 this(domain, name, value, path, null, secure);
173 if (maxAge < -1) {
174 throw new IllegalArgumentException("Invalid max age: " + Integer.toString(maxAge));
175 }
176 if (maxAge >= 0) {
177 setExpiryDate(new Date(System.currentTimeMillis() + maxAge * 1000L));
178 }
179 }
180
181 /***
182 * Returns the comment describing the purpose of this cookie, or
183 * <tt>null</tt> if no such comment has been defined.
184 *
185 * @see #setComment(String)
186 */
187 public String getComment() {
188 return cookieComment;
189 }
190
191 /***
192 * If a user agent (web browser) presents this cookie to a user, the
193 * cookie's purpose will be described using this comment.
194 *
195 * @see #getComment()
196 */
197 public void setComment(String comment) {
198 cookieComment = comment;
199 }
200
201 /***
202 * Returns my expiration {@link Date}, or <tt>null</tt>
203 * if none exists.
204 * <p><strong>Note:</strong> the object returned by this method is
205 * considered immutable. Changing it (e.g. using setTime()) could result
206 * in undefined behaviour. Do so at your peril. </p>
207 * @return my expiration {@link Date}, or <tt>null</tt>.
208 *
209 * @see #setExpiryDate(java.util.Date)
210 *
211 */
212 public Date getExpiryDate() {
213 return cookieExpiryDate;
214 }
215
216 /***
217 * Expiration setter.
218 * <p>
219 * Netscape's original proposal defined an Expires header that took
220 * a date value in a fixed-length variant format in place of Max-Age:
221 * <br>
222 * <tt>Wdy, DD-Mon-YY HH:MM:SS GMT</tt>
223 * <br>
224 * Note that the Expires date format contains embedded spaces, and that
225 * "old" cookies did not have quotes around values. Clients that
226 * implement to this specification should be aware of "old" cookies and
227 * Expires.
228 * </p>
229 * <p><strong>Note:</strong> the object returned by this method is considered
230 * immutable. Changing it (e.g. using setTime()) could result in undefined
231 * behaviour. Do so at your peril.</p>
232 *
233 * @param expiryDate the {@link Date} after which this cookie is no longer valid.
234 *
235 * @see #getExpiryDate
236 *
237 */
238 public void setExpiryDate (Date expiryDate) {
239 cookieExpiryDate = expiryDate;
240 }
241
242
243 /***
244 * Returns <tt>false</tt> if I should be discarded at the end
245 * of the "session"; <tt>true</tt> otherwise.
246 *
247 * @return <tt>false</tt> if I should be discarded at the end
248 * of the "session"; <tt>true</tt> otherwise
249 */
250 public boolean isPersistent() {
251 return (null != cookieExpiryDate);
252 }
253
254
255 /***
256 * Returns my domain.
257 *
258 * @see #setDomain(java.lang.String)
259 */
260 public String getDomain() {
261 return cookieDomain;
262 }
263
264 /***
265 * Sets my domain.
266 * <p>
267 * I should be presented only to hosts satisfying this domain
268 * name pattern. Read RFC 2109 for specific details of the syntax.
269 * Briefly, a domain name name begins with a dot (".foo.com") and means
270 * that hosts in that DNS zone ("www.foo.com", but not "a.b.foo.com")
271 * should see the cookie. By default, cookies are only returned to
272 * the host which saved them.
273 *
274 * @see #getDomain
275 */
276 public void setDomain(String domain) {
277 if (domain != null) {
278 int ndx = domain.indexOf(":");
279 if (ndx != -1) {
280 domain = domain.substring(0, ndx);
281 }
282 cookieDomain = domain.toLowerCase();
283 }
284 }
285
286
287 /***
288 * @return my path.
289 * @see #setPath(java.lang.String)
290 */
291 public String getPath() {
292 return cookiePath;
293 }
294
295 /***
296 * Sets my path.
297 * <p>
298 * I should be presented only with requests beginning with this path.
299 * See RFC 2109 for a specification of the default behaviour. Basically, URLs
300 * in the same "directory" as the one which set the cookie, and in subdirectories,
301 * can all see the cookie unless a different path is set.</p>
302 *
303 * @see #getPath
304 *
305 */
306 public void setPath(String path) {
307 cookiePath = path;
308 }
309
310 /***
311 * @return <code>true</code> if this cookie should only be sent over secure connections.
312 * @see #setSecure(boolean)
313 */
314 public boolean getSecure() {
315 return isSecure;
316 }
317
318 /***
319 * Set my secure flag.
320 * <p>
321 * When <tt>true</tt> the cookie should only be sent
322 * using a secure protocol (https). This should only be set when
323 * the cookie's originating server used a secure protocol to set the
324 * cookie's value.
325 *
326 * @see #getSecure()
327 */
328 public void setSecure (boolean secure) {
329 isSecure = secure;
330 }
331
332 /***
333 *
334 * @return the version of the HTTP cookie specification that I use.
335 *
336 * @see #setVersion(int)
337 *
338 */
339 public int getVersion() {
340 return cookieVersion;
341 }
342
343 /***
344 * Set the version of the HTTP cookie specification I report.
345 * <p>
346 * The current implementation only sends version 1 cookies.
347 * (See RFC 2109 for details.)</p>
348 *
349 * @see #getVersion
350 *
351 */
352 public void setVersion(int version) {
353 cookieVersion = version;
354 }
355
356 /***
357 * Return true if this cookie has expired.
358 * @return <tt>true</tt> if I have expired.
359 */
360 public boolean isExpired() {
361 return (cookieExpiryDate != null
362 && cookieExpiryDate.getTime() <= System.currentTimeMillis());
363 }
364
365 /***
366 * Return true if this cookie has expired according to the time passed in.
367 * @param now The current time.
368 * @return <tt>true</tt> if I have expired.
369 */
370 public boolean isExpired(Date now) {
371 return (cookieExpiryDate != null
372 && cookieExpiryDate.getTime() <= now.getTime());
373 }
374
375
376 /***
377 * Indicates whether the cookie had a path specified in a
378 * Path attribute in the set-cookie header. This value
379 * is important for generating the cookie header because
380 * RFC 2109 sec. 4.3.4 says that the cookie header should only
381 * include a $Path attribute if the cookie's path was specified
382 * in the set-cookie header.
383 *
384 * @see #isPathAttributeSpecified
385 * @param value True if the cookie's path came from a Path attribute.
386 */
387 public void setPathAttributeSpecified(boolean value) {
388 hasPathAttribute = value;
389 }
390
391 /***
392 * Returns true if cookie's path was set via a Path attribute in the
393 * set-cookie header.
394 *
395 * @see #setPathAttributeSpecified
396 * @return True if cookie's path was specified in the set-cookie header.
397 */
398 public boolean isPathAttributeSpecified() {
399 return hasPathAttribute;
400 }
401
402 /***
403 * Indicates whether the cookie had a domain specified in a
404 * Domain attribute in the set-cookie header. This value
405 * is important for generating the cookie header because
406 * RFC 2109 sec. 4.3.4 says that the cookie header should only
407 * include a $Domain attribute if the cookie's domain was specified
408 * in the set-cookie header.
409 *
410 * @see #isDomainAttributeSpecified
411 * @param value True if the cookie's domain came from a Domain attribute.
412 */
413 public void setDomainAttributeSpecified(boolean value) {
414 hasDomainAttribute = value;
415 }
416
417 /***
418 * Returns true if cookie's domain was set via a Domain attribute in the
419 * set-cookie header.
420 *
421 * @see #setDomainAttributeSpecified
422 * @return True if cookie's domain was specified in the set-cookie header.
423 */
424 public boolean isDomainAttributeSpecified() {
425 return hasDomainAttribute;
426 }
427
428 /***
429 * Returns a hash code in keeping with the
430 * {@link Object#hashCode} general hashCode contract.
431 * @return A hash code
432 */
433 public int hashCode() {
434 return super.hashCode()
435 ^ (null == cookiePath ? 0 : cookiePath.hashCode())
436 ^ (null == cookieDomain ? 0 : cookieDomain.hashCode());
437 }
438
439
440 /***
441 * Two cookies are equal if the name, path and domain match.
442 * @param obj The object to compare against.
443 * @return true if the two objects are equal.
444 */
445 public boolean equals(Object obj) {
446 LOG.trace("enter Cookie.equals(Object)");
447
448 if ((obj != null) && (obj instanceof Cookie)) {
449 Cookie that = (Cookie) obj;
450 return
451 (null == this.getName()
452 ? null == that.getName()
453 : this.getName().equals(that.getName()))
454 && (null == this.getPath()
455 ? null == that.getPath()
456 : this.getPath().equals(that.getPath()))
457 && (null == this.getDomain()
458 ? null == that.getDomain()
459 : this.getDomain().equals(that.getDomain()));
460 } else {
461 return false;
462 }
463 }
464
465
466 /***
467 * Return a string suitable for sending in a Cookie header.
468 * @return a string suitable for sending in a Cookie header.
469 */
470 public String toExternalForm() {
471 return CookiePolicy.getSpecByVersion(
472 getVersion()).formatCookie(this);
473 }
474
475 /***
476 * Return <tt>true</tt> if I should be submitted with a request with given
477 * attributes, <tt>false</tt> otherwise.
478 * @param domain the host to which the request is being submitted
479 * @param port the port to which the request is being submitted (currently
480 * ignored)
481 * @param path the path to which the request is being submitted
482 * @param secure <tt>true</tt> if the request is using the HTTPS protocol
483 * @param date the time at which the request is submitted
484 * @return true if the cookie matches
485 *
486 * @deprecated use {@link CookieSpec} interface
487 */
488 public boolean matches(
489 String domain, int port, String path, boolean secure, Date date) {
490
491 LOG.trace("enter Cookie.matches(Strinng, int, String, boolean, Date");
492 CookieSpec matcher = CookiePolicy.getDefaultSpec();
493 return matcher.match(domain, port, path, secure, this);
494 }
495
496 /***
497 * Return <tt>true</tt> if I should be submitted with a request with given
498 * attributes, <tt>false</tt> otherwise.
499 * @param domain the host to which the request is being submitted
500 * @param port the port to which the request is being submitted (currently
501 * ignored)
502 * @param path the path to which the request is being submitted
503 * @param secure True if this cookie has the secure flag set
504 * @return true if I should be submitted as above.
505 * @deprecated use {@link CookieSpec} interface
506 */
507 public boolean matches(
508 String domain, int port, String path, boolean secure) {
509 LOG.trace("enter Cookie.matches(String, int, String, boolean");
510 return matches(domain, port, path, secure, new Date());
511 }
512
513 /***
514 * Create a <tt>Cookie</tt> header containing
515 * all non-expired cookies in <i>cookies</i>,
516 * associated with the given <i>domain</i> and
517 * <i>path</i>, assuming the connection is not
518 * secure.
519 * <p>
520 * If no cookies match, returns null.
521 *
522 * @param domain The domain
523 * @param path The path
524 * @param cookies The cookies to use
525 * @return The new header.
526 * @deprecated use {@link CookieSpec} interface
527 */
528 public static Header createCookieHeader(String domain, String path,
529 Cookie[] cookies) {
530
531 LOG.trace("enter Cookie.createCookieHeader(String,String,Cookie[])");
532 return Cookie.createCookieHeader(domain, path, false, cookies);
533 }
534
535 /***
536 * Create a <tt>Cookie</tt> header containing
537 * all non-expired cookies in <i>cookies</i>,
538 * associated with the given <i>domain</i>, <i>path</i> and
539 * <i>https</i> setting.
540 * <p>
541 * If no cookies match, returns null.
542 *
543 * @param domain The domain
544 * @param path The path
545 * @param secure True if this cookie has the secure flag set
546 * @param cookies The cookies to use.
547 * @return The new header
548 * @exception IllegalArgumentException if domain or path is null
549 *
550 * @deprecated use {@link CookieSpec} interface
551 */
552 public static Header createCookieHeader(String domain, String path,
553 boolean secure, Cookie[] cookies)
554 throws IllegalArgumentException {
555
556 LOG.trace("enter Cookie.createCookieHeader("
557 + "String, String, boolean, Cookie[])");
558
559 // Make sure domain isn't null here. Path will be validated in
560 // subsequent call to createCookieHeader
561 if (domain == null) {
562 throw new IllegalArgumentException("null domain in "
563 + "createCookieHeader.");
564 }
565 // parse port from domain, if any
566 int port = secure ? 443 : 80;
567 int ndx = domain.indexOf(":");
568 if (ndx != -1) {
569 try {
570 port = Integer.parseInt(domain.substring(ndx + 1,
571 domain.length()));
572 } catch (NumberFormatException e) {
573 // ignore?, but at least LOG
574 LOG.warn("Cookie.createCookieHeader(): "
575 + "Invalid port number in domain " + domain);
576 }
577 }
578 return Cookie.createCookieHeader(domain, port, path, secure, cookies);
579 }
580
581 /***
582 * Create a <tt>Cookie</tt> header containing
583 * all non-expired cookies in <i>cookies</i>,
584 * associated with the given <i>domain</i>, <i>port</i>,
585 * <i>path</i> and <i>https</i> setting.
586 * <p>
587 * If no cookies match, returns null.
588 *
589 * @param domain The domain
590 * @param port The port
591 * @param path The path
592 * @param secure True if this cookie has the secure flag set
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 public static Header createCookieHeader(String domain, int port,
600 String path, boolean secure, Cookie[] cookies)
601 throws IllegalArgumentException {
602 LOG.trace("enter Cookie.createCookieHeader(String, int, String, boolean, Cookie[])");
603 return Cookie.createCookieHeader(domain, port, path, secure, new Date(), cookies);
604 }
605
606 /***
607 * Create a <tt>Cookie</tt> header containing all cookies in <i>cookies</i>,
608 * associated with the given <i>domain</i>, <i>port</i>, <i>path</i> and
609 * <i>https</i> setting, and which are not expired according to the given
610 * <i>date</i>.
611 * <p>
612 * If no cookies match, returns null.
613 *
614 * @param domain The domain
615 * @param port The port
616 * @param path The path
617 * @param secure True if this cookie has the secure flag set
618 * @param now The date to check for expiry
619 * @param cookies The cookies to use.
620 * @return The new header
621 * @throws IllegalArgumentException if domain or path is null
622 *
623 * @deprecated use {@link CookieSpec} interface
624 */
625
626 public static Header createCookieHeader(
627 String domain, int port, String path, boolean secure,
628 Date now, Cookie[] cookies)
629 throws IllegalArgumentException {
630
631 LOG.trace("enter Cookie.createCookieHeader(String, int, String, boolean, Date, Cookie[])");
632 CookieSpec matcher = CookiePolicy.getDefaultSpec();
633 cookies = matcher.match(domain, port, path, secure, cookies);
634 if ((cookies != null) && (cookies.length > 0)) {
635 return matcher.formatCookieHeader(cookies);
636 } else {
637 return null;
638 }
639 }
640
641 /***
642 * <p>Compares two cookies to determine order for cookie header.</p>
643 * <p>Most specific should be first. </p>
644 * <p>This method is implemented so a cookie can be used as a comparator for
645 * a SortedSet of cookies. Specifically it's used above in the
646 * createCookieHeader method.</p>
647 * <p>The compare only compares the path of the cookie, see section 4.3.4
648 * of RFC2109</p>
649 * @param o1 The first object to be compared
650 * @param o2 The second object to be compared
651 * @return See {@link java.util.Comparator#compare(Object,Object)}
652 */
653 public int compare(Object o1, Object o2) {
654 LOG.trace("enter Cookie.compare(Object, Object)");
655
656 if (!(o1 instanceof Cookie)) {
657 throw new ClassCastException(o1.getClass().getName());
658 }
659 if (!(o2 instanceof Cookie)) {
660 throw new ClassCastException(o2.getClass().getName());
661 }
662 Cookie c1 = (Cookie) o1;
663 Cookie c2 = (Cookie) o2;
664 if (c1.getPath() == null && c2.getPath() == null) {
665 return 0;
666 } else if (c1.getPath() == null) {
667 // null is assumed to be "/"
668 if (c2.getPath().equals(CookieSpec.PATH_DELIM)) {
669 return 0;
670 } else {
671 return -1;
672 }
673 } else if (c2.getPath() == null) {
674 // null is assumed to be "/"
675 if (c1.getPath().equals(CookieSpec.PATH_DELIM)) {
676 return 0;
677 } else {
678 return 1;
679 }
680 } else {
681 return STRING_COLLATOR.compare(c1.getPath(), c2.getPath());
682 }
683 }
684
685 /***
686 * Return a {@link String} representation of me.
687 * @see #toExternalForm
688 */
689 public String toString() {
690 return toExternalForm();
691 }
692
693 /***
694 * Parses the Set-Cookie {@link Header} into an array of
695 * <tt>Cookie</tt>s, assuming that the cookies were recieved
696 * on an insecure channel.
697 *
698 * @param domain the domain from which the {@link Header} was received
699 * @param port the port from which the {@link Header} was received
700 * (currently ignored)
701 * @param path the path from which the {@link Header} was received
702 * @param setCookie the <tt>Set-Cookie</tt> {@link Header} received from the
703 * server
704 * @return an array of <tt>Cookie</tt>s parsed from the Set-Cookie {@link
705 * Header}
706 * @throws HttpException if an exception occurs during parsing
707 * @throws IllegalArgumentException if domain or path are null
708 *
709 * @deprecated use {@link CookieSpec} interface
710 */
711 public static Cookie[] parse(
712 String domain, int port, String path, Header setCookie)
713 throws HttpException, IllegalArgumentException {
714
715 LOG.trace("enter Cookie.parse(String, int, String, Header)");
716 return Cookie.parse(domain, port, path, false, setCookie);
717 }
718
719 /***
720 * Parses the Set-Cookie {@link Header} into an array of
721 * <tt>Cookie</tt>s, assuming that the cookies were recieved
722 * on an insecure channel.
723 *
724 * @param domain the domain from which the {@link Header} was received
725 * @param path the path from which the {@link Header} was received
726 * @param setCookie the <tt>Set-Cookie</tt> {@link Header} received from the
727 * server
728 * @return an array of <tt>Cookie</tt>s parsed from the Set-Cookie {@link
729 * Header}
730 * @throws HttpException if an exception occurs during parsing
731 * @throws IllegalArgumentException if domain or path are null
732 *
733 * @deprecated use {@link CookieSpec} interface
734 */
735 public static Cookie[] parse(String domain, String path, Header setCookie)
736 throws HttpException, IllegalArgumentException {
737 LOG.trace("enter Cookie.parse(String, String, Header)");
738 return Cookie.parse (domain, 80, path, false, setCookie);
739 }
740
741 /***
742 * Parses the Set-Cookie {@link Header} into an array of
743 * <tt>Cookie</tt>s.
744 *
745 * @param domain the domain from which the {@link Header} was received
746 * @param path the path from which the {@link Header} was received
747 * @param secure <tt>true</tt> when the header was recieved over a secure
748 * channel
749 * @param setCookie the <tt>Set-Cookie</tt> {@link Header} received from the
750 * server
751 * @return an array of <tt>Cookie</tt>s parsed from the Set-Cookie {@link
752 * Header}
753 * @throws HttpException if an exception occurs during parsing
754 * @throws IllegalArgumentException if domain or path are null
755 *
756 * @deprecated use {@link CookieSpec} interface
757 */
758 public static Cookie[] parse(String domain, String path,
759 boolean secure, Header setCookie)
760 throws HttpException, IllegalArgumentException {
761
762 LOG.trace ("enter Cookie.parse(String, String, boolean, Header)");
763 return Cookie.parse (
764 domain, (secure ? 443 : 80), path, secure, setCookie);
765 }
766
767 /***
768 * Parses the Set-Cookie {@link Header} into an array of
769 * <tt>Cookie</tt>s.
770 *
771 * <P>The syntax for the Set-Cookie response header is:
772 *
773 * <PRE>
774 * set-cookie = "Set-Cookie:" cookies
775 * cookies = 1#cookie
776 * cookie = NAME "=" VALUE * (";" cookie-av)
777 * NAME = attr
778 * VALUE = value
779 * cookie-av = "Comment" "=" value
780 * | "Domain" "=" value
781 * | "Max-Age" "=" value
782 * | "Path" "=" value
783 * | "Secure"
784 * | "Version" "=" 1*DIGIT
785 * </PRE>
786 *
787 * @param domain the domain from which the {@link Header} was received
788 * @param port The port from which the {@link Header} was received.
789 * @param path the path from which the {@link Header} was received
790 * @param secure <tt>true</tt> when the {@link Header} was received over
791 * HTTPS
792 * @param setCookie the <tt>Set-Cookie</tt> {@link Header} received from
793 * the server
794 * @return an array of <tt>Cookie</tt>s parsed from the Set-Cookie {@link
795 * Header}
796 * @throws HttpException if an exception occurs during parsing
797 *
798 * @deprecated use {@link CookieSpec} interface
799 */
800 public static Cookie[] parse(String domain, int port, String path,
801 boolean secure, Header setCookie)
802 throws HttpException {
803
804 LOG.trace("enter Cookie.parse(String, int, String, boolean, Header)");
805
806 CookieSpec parser = CookiePolicy.getDefaultSpec();
807 Cookie[] cookies = parser.parse(domain, port, path, secure, setCookie);
808
809 for (int i = 0; i < cookies.length; i++) {
810 final Cookie cookie = cookies[i];
811 final CookieSpec validator
812 = CookiePolicy.getSpecByVersion(cookie.getVersion());
813 validator.validate(domain, port, path, secure, cookie);
814 }
815 return cookies;
816 }
817
818 // ----------------------------------------------------- Instance Variables
819
820 /*** My comment. */
821 private String cookieComment;
822
823 /*** My domain. */
824 private String cookieDomain;
825
826 /*** My expiration {@link Date}. */
827 private Date cookieExpiryDate;
828
829 /*** My path. */
830 private String cookiePath;
831
832 /*** My secure flag. */
833 private boolean isSecure;
834
835 /***
836 * Specifies if the set-cookie header included a Path attribute for this
837 * cookie
838 */
839 private boolean hasPathAttribute = false;
840
841 /***
842 * Specifies if the set-cookie header included a Domain attribute for this
843 * cookie
844 */
845 private boolean hasDomainAttribute = false;
846
847 /*** The version of the cookie specification I was created from. */
848 private int cookieVersion = 0;
849
850 // -------------------------------------------------------------- Constants
851
852 /***
853 * Collator for Cookie comparisons. Could be replaced with references to
854 * specific Locales.
855 */
856 private static final RuleBasedCollator STRING_COLLATOR =
857 (RuleBasedCollator) RuleBasedCollator.getInstance(
858 new Locale("en", "US", ""));
859
860 /*** Log object for this class */
861 private static final Log LOG = LogFactory.getLog(Cookie.class);
862
863 }
864
This page was automatically generated by Maven