001: /*
002: * Cookie.java February 2001
003: *
004: * Copyright (C) 2001, Niall Gallagher <niallg@users.sf.net>
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General
016: * Public License along with this library; if not, write to the
017: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
018: * Boston, MA 02111-1307 USA
019: */
020:
021: package simple.util.net;
022:
023: import java.io.Serializable;
024:
025: /**
026: * This class is used to represent a generic cookie. This exposes
027: * the fields that a cookie can have. The <code>Cookie</code> object
028: * implements <code>java.io.Serializable</code> which means that it
029: * can be stored. This is useful when the server wants to remember
030: * the <code>Cookies</code> that it has received.
031: * <p>
032: * By default the version of the <code>Cookie</code> is set to 1.
033: * The version can be configured using the <code>setVersion</code>
034: * method. The domain, path, security, and expiry of the cookie can
035: * also be set using their respective set methods.
036: * <p>
037: * The <code>toString</code> method allows the <code>Cookie</code>
038: * to be converted back into text form. This text form converts the
039: * cookie according to the Set-Cookie header form. This is done so
040: * that a created <code>Cookie</code> instance can be converted
041: * to a string which can be used as a a HTTP header.
042: *
043: * @author Niall Gallagher
044: */
045: public class Cookie implements Serializable {
046:
047: /**
048: * The name attribute of this <code>Cookie</code>.
049: */
050: private String name;
051:
052: /**
053: * The value attribute of this <code>Cookie</code>.
054: */
055: private String value;
056:
057: /**
058: * Represents the value of the path for this cookie.
059: */
060: private String path;
061:
062: /**
063: * Represents the value of the domain attribute.
064: */
065: private String domain;
066:
067: /**
068: * Determines whether the cookie should be secure.
069: */
070: private boolean secure;
071:
072: /**
073: * Represents the value of the version attribute.
074: */
075: private int version = 1;
076:
077: /**
078: * Represents the duration in seconds of the cookie.
079: */
080: private int expiry = -1;
081:
082: /**
083: * Constructor of the <code>Cookie</code> that does not need
084: * the name or value to be set. This allows the object to be
085: * extended without the need to supply the name and value of
086: * the cookie. If this constructor is used then the name and
087: * values retrieved should not be null values.
088: */
089: protected Cookie() {
090: super ();
091: }
092:
093: /**
094: * Constructor of the <code>Cookie</code> that uses a default
095: * version of 1, which is used by RFC 2109. This contains none
096: * of the optional attributes, such as domain and path. These
097: * optional attributes can be set using the set methods.
098: * <p>
099: * The name must conform to RFC 2109, which means that it can
100: * contain only ASCII alphanumeric characters and cannot have
101: * commas, white space, or semicolon characters.
102: *
103: * @param name this is the name of this <code>Cookie</code>
104: * @param value this is the value of this <code>Cookie</code>
105: */
106: public Cookie(String name, String value) {
107: this (name, value, "/");
108: }
109:
110: /**
111: * Constructor of the <code>Cookie</code> that uses a default
112: * version of 1, which is used by RFC 2109. This allows the
113: * path attribute to be specified for on construction. Other
114: * attributes can be set using the set methods provided.
115: * <p>
116: * The name must conform to RFC 2109, which means that it can
117: * contain only ASCII alphanumeric characters and cannot have
118: * commas, white space, or semicolon characters.
119: *
120: * @param name this is the name of this <code>Cookie</code>
121: * @param value this is the value of this <code>Cookie</code>
122: * @param path the path attribute of this <code>Cookie</code>
123: */
124: public Cookie(String name, String value, String path) {
125: this .value = value;
126: this .name = name;
127: this .path = path;
128: }
129:
130: /**
131: * This returns the version for this cookie. The version is
132: * not optional and so will always return the version this
133: * cookie uses. If no version number is specified this will
134: * return a version of 1, to comply with RFC 2109.
135: *
136: * @return the version value from this <code>Cookie</code>
137: */
138: public int getVersion() {
139: return version;
140: }
141:
142: /**
143: * This enables the version of the <code>Cookie</code> to be
144: * set. By default the version of the <code>Cookie</code> is
145: * set to 1. It is not advisable to set the version higher
146: * than 1, unless it is known that the client will accept it.
147: * <p>
148: * Some old browsers can only handle cookie version 0. This
149: * can be used to comply with the original Netscape cookie
150: * specification. Version 1 complies with RFC 2109.
151: *
152: * @param version this is the version number for the cookie
153: */
154: public void setVersion(int version) {
155: this .version = version;
156: }
157:
158: /**
159: * This returns the name for this cookie. The name and value
160: * attributes of a cookie define what the <code>Cookie</code>
161: * is for, these values will always be present. These are
162: * mandatory for both the Cookie and Set-Cookie headers.
163: * <p>
164: * Because the cookie may be stored by name, the cookie name
165: * cannot be modified after the creation of the cookie object.
166: *
167: * @return the name from this <code>Cookie</code> object
168: */
169: public String getName() {
170: return name;
171: }
172:
173: /**
174: * This returns the value for this cookie. The name and value
175: * attributes of a cookie define what the <code>Cookie</code>
176: * is for, these values will always be present. These are
177: * mandatory for both the Cookie and Set-Cookie headers.
178: *
179: * @return the value from this <code>Cookie</code> object
180: */
181: public String getValue() {
182: return value;
183: }
184:
185: /**
186: * This enables the value of the cookie to be changed. This
187: * can be set to any value the server wishes to send. Cookie
188: * values can contain space characters as they are transmitted
189: * in quotes. For example a value of <code>some value</code>
190: * is perfectly legal. However for maximum compatibility
191: * across the different plaforms such as PHP, JavaScript and
192: * others, quotations should be avoided. If quotations are
193: * required they must be added to the string. For example a
194: * quoted value could be created as <code>"some value"</code>.
195: *
196: * @param value this is the new value of this cookie object
197: */
198: public void setValue(String value) {
199: this .value = value;
200: }
201:
202: /**
203: * This determines whether the cookie is secure. The cookie
204: * is secure if it has the "secure" token set, as defined
205: * by RFC 2109. If this token is set then the cookie is only
206: * sent over secure channels such as SSL and TLS and ensures
207: * that a third party cannot intercept and spoof the cookie.
208: *
209: * @return this returns true if the "secure" token is set
210: */
211: public boolean getSecure() {
212: return secure;
213: }
214:
215: /**
216: * This is used to determine if the client browser should send
217: * this cookie over a secure protocol. If this is true then
218: * the client browser should only send the cookie over secure
219: * channels such as SSL and TLS. This ensures that the value
220: * of the cookie cannot be intercepted by a third party.
221: *
222: * @param secure if true then the cookie should be protected
223: */
224: public void setSecure(boolean secure) {
225: this .secure = secure;
226: }
227:
228: /**
229: * This returns the number of seconds a cookie lives for. This
230: * determines how long the cookie will live on the client side.
231: * If the expiry is less than zero the cookie lifetime is the
232: * duration of the client browser session, if it is zero then
233: * the cookie will be deleted from the client browser.
234: *
235: * @return returns the duration in seconds the cookie lives
236: */
237: public int getExpiry() {
238: return expiry;
239: }
240:
241: /**
242: * This allows a lifetime to be specified for the cookie. This
243: * will make use of the "max-age" token specified by RFC 2109
244: * the specifies the number of seconds a browser should keep
245: * a cookie for. This is useful if the cookie is to be kept
246: * beyond the lifetime of the client session. If the valie of
247: * this is zero then this will remove the client cookie, if
248: * it is less than zero then the "max-age" field is ignored.
249: *
250: * @param expiry the duration in seconds the cookie lives
251: */
252: public void setExpiry(int expiry) {
253: this .expiry = expiry;
254: }
255:
256: /**
257: * This returns the path for this cookie. The path is in both
258: * the Cookie and Set-Cookie headers and so may return null
259: * if there is no domain value. If the <code>toString</code>
260: * or <code>toClientString</code> is invoked the path will
261: * not be present if the path attribute is null.
262: *
263: * @return this returns the path value from this cookie
264: */
265: public String getPath() {
266: return path;
267: }
268:
269: /**
270: * This is used to set the cookie path for this cookie. This
271: * is set so that the cookie can specify the directories that
272: * the cookie is sent with. For example if the path attribute
273: * is set to <code>/pub/bin</code>, then requests for the
274: * resource <code>http://hostname:port/pub/bin/README</code>
275: * will be issued with this cookie. The cookie is issued for
276: * all resources in the path and all subdirectories.
277: *
278: * @param path this is the path value for this cookie object
279: */
280: public void setPath(String path) {
281: this .path = path;
282: }
283:
284: /**
285: * This returns the domain for this cookie. The domain is in
286: * both the Cookie and Set-Cookie headers and so may return
287: * null if there is no domain value. If either the
288: * <code>toString</code> or <code>toClientString</code> is
289: * invoked the domain will not be present if this is null.
290: *
291: * @return this returns the domain value from this cookie
292: */
293: public String getDomain() {
294: return domain;
295: }
296:
297: /**
298: * This enables the domain for this <code>Cookie</code> to be
299: * set. The form of the domain is specified by RFC 2109. The
300: * value can begin with a dot, like <code>.host.com</code>.
301: * This means that the cookie is visible within a specific
302: * DNS zone like <code>www.host.com</code>. By default this
303: * value is null which means it is sent back to its origin.
304: *
305: * @param domain this is the domain value for this cookie
306: */
307: public void setDomain(String domain) {
308: this .domain = domain;
309: }
310:
311: /**
312: * This will give the correct string value of this cookie. This
313: * will generate the cookie text with only the values that were
314: * given with this cookie. If there are no optional attributes
315: * like $Path or $Domain these are left blank. This returns the
316: * encoding as it would be for the HTTP Cookie header.
317: *
318: * @return this returns the Cookie header encoding of this
319: */
320: public String toClientString() {
321: return "$Version=" + version + "; " + name + "=" + value
322: + (path == null ? "" : "; $Path=" + path)
323: + (domain == null ? "" : "; $Domain=" + domain);
324: }
325:
326: /**
327: * The <code>toString</code> method converts the cookie to the
328: * Set-Cookie value. This can be used to send the HTTP header
329: * to a client browser. This uses a format that has been tested
330: * with various browsers. This is required as some browsers
331: * do not perform flexible parsing of the Set-Cookie value.
332: * <p>
333: * Netscape and IE-5.0 cant or wont handle <code>Path</code>
334: * it must be <code>path</code> also Netscape can not handle
335: * the path in quotations such as <code>"/path"</code> it must
336: * be <code>/path</code>. This value is never in quotations.
337: * <p>
338: * For maximum compatibility cookie values are not transmitted
339: * in quotations. This is done to ensure that platforms like
340: * PHP, JavaScript and various others that don't comply with
341: * RFC 2109 can transparently access the sent cookies.
342: *
343: * @return this returns a Set-Cookie encoding of the cookie
344: */
345: public String toString() {
346: return name + "=" + value + "; version=" + version
347: + (path == null ? "" : "; path=" + path)
348: + (domain == null ? "" : "; domain=" + domain)
349: + (expiry < 0 ? "" : "; max-age=" + expiry)
350: + (secure ? "; secure;" : ";");
351: }
352: }
|