home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / VCAFE.3.0A / Main.bin / Cookie.java < prev    next >
Text File  |  1998-04-21  |  11KB  |  344 lines

  1. /*
  2.  * @(#)Cookie.java    1.31 97/10/08
  3.  * 
  4.  * Copyright (c) 1996-1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.0
  20.  */
  21.  
  22. package javax.servlet.http;
  23.  
  24. import java.io.IOException;
  25. import javax.servlet.ServletOutputStream;
  26. import javax.servlet.http.HttpServletRequest;
  27. import javax.servlet.http.HttpServletResponse;
  28. import java.util.Enumeration;
  29. import java.util.StringTokenizer;
  30. import java.util.Vector;
  31.  
  32.  
  33. /**
  34.  * This class represents a "Cookie", as used for session management with
  35.  * HTTP and HTTPS protocols.  Cookies are used to get user agents (web
  36.  * browsers etc) to hold small amounts of state associated with a user's
  37.  * web browsing.  Common applications for cookies include storing user
  38.  * preferences, automating low security user signon facilities, and helping
  39.  * collect data used for "shopping cart" style applications.
  40.  *
  41.  * <HR>
  42.  *
  43.  * <P> Cookies are named, and have a single value.  They may have optional
  44.  * attributes, including a comment presented to the user, path and domain
  45.  * qualifiers for which hosts see the cookie, a maximum age, and a version.
  46.  * Current web browsers often have bugs in how they treat those attributes,
  47.  * so interoperability can be improved by not relying on them heavily.
  48.  *
  49.  * <P> Cookies are assigned by servers, using fields added to HTTP response
  50.  * headers.  In this API, cookies are saved one at a time into such HTTP
  51.  * response headers, using the 
  52.  * <em>javax.servlet.http.HttpServletResponse.addCookie</em> method.  User
  53.  * agents are expected to support twenty cookies per host, of at least four
  54.  * kilobytes each; use of large numbers of cookies is discouraged.  
  55.  *
  56.  * <P> Cookies are passed back to those servers using fields added to HTTP
  57.  * request headers.  In this API, HTTP request fields are retrieved using
  58.  * the cookie module's
  59.  * <em>javax.servlet.http.HttpServletRequest.getCookies</em> method. 
  60.  * This returns all of the cookies found in the request.  Several cookies
  61.  * with the same name can be returned; they have different path attributes,
  62.  * but those attributes will not be visible when using "old format" cookies.
  63.  *
  64.  * <P> Cookies affect the caching of the web pages used to set their values.
  65.  * At this time, none of the sophisticated HTTP/1.1 cache control models
  66.  * are supported by this class.  Standard HTTP/1.0 caches will not cache
  67.  * pages which contain cookies created by this class.
  68.  *
  69.  * <HR>
  70.  *
  71.  * <P> Cookies are being standardized by the IETF.  This class supports
  72.  * the original Cookie specification (from Netscape Communications Corp.)
  73.  * as well as the updated RFC 2109 specification.  By default, cookies
  74.  * are stored using the original specification.  This promotes maximal
  75.  * interoperability; an updated RFC will provide better interoperability
  76.  * by defining a new HTTP header field for setting cookies.
  77.  *
  78.  * @version    1.31, 10/08/97
  79.  */
  80. public class Cookie implements Cloneable
  81.     // XXX would implement java.io.Serializable too, but can't do that
  82.     // so long as sun.servlet.* must run on older JDK 1.02 JVMs which
  83.     // don't include that support.
  84. {
  85.  
  86.     //
  87.     // The value of the cookie itself.
  88.     //
  89.     private String name;    // NAME= ... "$Name" style is reserved
  90.     private String value;    // value of NAME
  91.  
  92.     //
  93.     // Attributes encoded in the header's cookie fields.
  94.     //
  95.     private String comment;    // ;Comment=VALUE ... describes cookie's use
  96.                 // ;Discard ... implied by maxAge < 0
  97.     private String domain;    // ;Domain=VALUE ... domain that sees cookie
  98.     private int maxAge = -1;    // ;Max-Age=VALUE ... cookies auto-expire
  99.     private String path;    // ;Path=VALUE ... URLs that see the cookie
  100.     private boolean secure;    // ;Secure ... e.g. use SSL
  101.     private int version = 0;    // ;Version=1 ... means RFC 2109++ style
  102.  
  103.  
  104.     /**
  105.      * Defines a cookie with an initial name/value pair.  The name must
  106.      * be an HTTP/1.1 "token" value; alphanumeric ASCII strings work.
  107.      * Names starting with a "$" character are reserved by RFC 2109.
  108.      *
  109.      * @param name name of the cookie
  110.      * @param value value of the cookie
  111.      * @throws IllegalArgumentException if the cookie name is not
  112.      *    an HTTP/1.1 "token", or if it is one of the tokens reserved
  113.      *    for use by the cookie protocol
  114.      */
  115.     public Cookie (String name, String value) {
  116.     if (!isToken (name)
  117.         || name.equalsIgnoreCase ("Comment")    // rfc2019
  118.         || name.equalsIgnoreCase ("Discard")    // 2019++
  119.         || name.equalsIgnoreCase ("Domain")
  120.         || name.equalsIgnoreCase ("Expires")    // (old cookies)
  121.         || name.equalsIgnoreCase ("Max-Age")    // rfc2019
  122.         || name.equalsIgnoreCase ("Path")
  123.         || name.equalsIgnoreCase ("Secure")
  124.         || name.equalsIgnoreCase ("Version")
  125.         )
  126.         throw new IllegalArgumentException ("cookie name: " + name);
  127.     this.name = name;
  128.     this.value = value;
  129.     }
  130.  
  131.  
  132.  
  133.     /**
  134.      * If a user agent (web browser) presents this cookie to a user, the
  135.      * cookie's purpose will be described using this comment.  This is
  136.      * not supported by version zero cookies.
  137.      *
  138.      * @see getComment
  139.      */
  140.     public void setComment (String purpose) {
  141.     comment = purpose;
  142.     }
  143.  
  144.     /**
  145.      * Returns the comment describing the purpose of this cookie, or
  146.      * null if no such comment has been defined.
  147.      *
  148.      * @see setComment
  149.      */ 
  150.     public String getComment () {
  151.     return comment;
  152.     }
  153.  
  154.  
  155.     /**
  156.      * This cookie should be presented only to hosts satisfying this domain
  157.      * name pattern.  Read RFC 2109 for specific details of the syntax.
  158.      * Briefly, a domain name name begins with a dot (".foo.com") and means
  159.      * that hosts in that DNS zone ("www.foo.com", but not "a.b.foo.com")
  160.      * should see the cookie.  By default, cookies are only returned to
  161.      * the host which saved them.
  162.      *
  163.      * @see getDomain
  164.      */
  165.     public void setDomain (String pattern) {
  166.     domain = pattern.toLowerCase ();    // IE allegedly needs this
  167.     }
  168.  
  169.     /**
  170.      * Returns the domain of this cookie.
  171.      *
  172.      * @see setDomain
  173.      */ 
  174.     public String getDomain () {
  175.     return domain;
  176.     }
  177.  
  178.  
  179.     /**
  180.      * Sets the maximum age of the cookie.  The cookie will expire
  181.      * after that many seconds have passed.  Negative values indicate
  182.      * the default behaviour:  the cookie is not stored persistently,
  183.      * and will be deleted when the user agent (web browser) exits.
  184.      * A zero value causes the cookie to be deleted.
  185.      *
  186.      * @see getMaxAge
  187.      */
  188.     public void setMaxAge (int expiry) {
  189.     maxAge = expiry;
  190.     }
  191.  
  192.     /**
  193.      * Returns the maximum specified age of the cookie.  If none was
  194.      * specified, a negative value is returned, indicating the default
  195.      * behaviour described with <em>setMaxAge</em>.
  196.      *
  197.      * @see setMaxAge
  198.      */
  199.     public int getMaxAge () {
  200.     return maxAge;
  201.     }
  202.  
  203.  
  204.     /**
  205.      * This cookie should be presented only with requests beginning
  206.      * with this URL.  Read RFC 2109 for a specification of the default
  207.      * behaviour.  Basically, URLs in the same "directory" as the one
  208.      * which set the cookie, and in subdirectories, can all see the
  209.      * cookie unless a different path is set.
  210.      *
  211.      * @see getPath
  212.      */
  213.     public void setPath (String uri) {
  214.     path = uri;
  215.     }
  216.  
  217.     /**
  218.      * Returns the prefix of all URLs for which this cookie is targetted.
  219.      *
  220.      * @see setPath
  221.      */ 
  222.     public String getPath () {
  223.     return path;
  224.     }
  225.  
  226.  
  227.     /**
  228.      * Indicates to the user agent that the cookie should only be sent
  229.      * using a secure protocol (https).  This should only be set when
  230.      * the cookie's originating server used a secure protocol to set the
  231.      * cookie's value.
  232.      *
  233.      * @see getSecure
  234.      */
  235.     public void setSecure (boolean flag) {
  236.     secure = flag;
  237.     }
  238.  
  239.     /**
  240.      * Returns the value of the 'secure' flag.
  241.      *
  242.      * @see setSecure
  243.      */
  244.     public boolean getSecure () {
  245.     return secure;
  246.     }
  247.  
  248.  
  249.     /**
  250.      * Returns the name of the cookie.  This name may not be changed
  251.      * after the cookie is created.
  252.      */
  253.     public String getName () {
  254.     return name;
  255.     }
  256.  
  257.  
  258.     /**
  259.      * Sets the value of the cookie.  BASE64 encoding is suggested for
  260.      * use with binary values.
  261.      *
  262.      * <P> With version zero cookies, you need to be careful about the
  263.      * kinds of values you use.  Values with various special characters
  264.      * (whitespace, brackets and parentheses, the equals sign, comma,
  265.      * double quote, slashes, question marks, the "at" sign, colon, and
  266.      * semicolon) should be avoided.  Empty values may not behave the
  267.      * same way on all browsers.
  268.      *
  269.      * @see getValue
  270.      */
  271.     public void setValue (String newValue) {
  272.     value = newValue;
  273.     }
  274.  
  275.     /**
  276.      * Returns the value of the cookie.
  277.      *
  278.      * @see setValue
  279.      */
  280.     public String getValue () {
  281.     return value;
  282.     }
  283.  
  284.  
  285.     /**
  286.      * Returns the version of the cookie.  Version 1 complies with
  287.      * RFC 2109, version 0 indicates the original version, as specified
  288.      * by Netscape.  Newly constructed cookies use version 0 by default,
  289.      * to maximize interoperability.  Cookies provided by a user agent
  290.      * will identify the cookie version used by the browser.
  291.      *
  292.      * @see setVersion
  293.      */
  294.     public int getVersion () {
  295.     return version;
  296.     }
  297.  
  298.     /**
  299.      * Sets the version of the cookie protocol used when this cookie saves
  300.      * itself.  Since the IETF standards are still being finalized, consider
  301.      * version 1 as experimental; do not use it (yet) on production sites.
  302.      *
  303.      * @see getVersion
  304.      */
  305.     public void setVersion (int v) {
  306.     version = v;
  307.     }
  308.  
  309.  
  310.     //
  311.     // from RFC 2068, token special case characters
  312.     //
  313.     private static final String tspecials = "()<>@,;:\\\"/[]?={} \t";
  314.  
  315.  
  316.     /*
  317.      * Return true iff the string counts as an HTTP/1.1 "token".
  318.      */
  319.     private boolean isToken (String value) {
  320.     int len = value.length ();
  321.  
  322.     for (int i = 0; i < len; i++) {
  323.         char c = value.charAt (i);
  324.  
  325.         if (c < 0x20 || c >= 0x7f || tspecials.indexOf (c) != -1)
  326.         return false;
  327.     }
  328.     return true;
  329.     }
  330.  
  331.  
  332.     /**
  333.      * Returns a copy of this object.
  334.      */
  335.     public Object clone () {
  336.     try {
  337.         return super.clone ();
  338.     } catch (CloneNotSupportedException e) {
  339.         throw new RuntimeException (e.getMessage ());
  340.     }
  341.     }
  342. }
  343.  
  344.