001: /*
002: * Copyright (c) 1998-2001 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package javax.servlet.http;
030:
031: /**
032: * Encapsulates HTTP cookies.
033: *
034: * <p/>Cookies are use to keep track of users for sessions and to
035: * recognize users back for personalization.
036: *
037: * <p/>When deleting cookies or changing the time, it's important to
038: * set the same domain and path as originally passed. Browsers distinguish
039: * cookies with different domain and path.
040: *
041: * <code><pre>
042: * Cookie myCookie = new Cookie("mycookie", "myvalue");
043: * myCookie.setPath("/path");
044: * myCookie.setDomain("mydom.com");
045: * // will live for a month
046: * myCookie.setMaxAge(60 * 24 * 3600);
047: * response.addCookie(myCookie);
048: * </pre></code>
049: *
050: * <p/>To delete the above cookie, you'll need to do something like the
051: * following:
052: *
053: * <code><pre>
054: * Cookie myCookie = new Cookie("mycookie", "myvalue");
055: * myCookie.setPath("/path");
056: * myCookie.setDomain("mydom.com");
057: * // kill the cookies
058: * myCookie.setMaxAge(0);
059: * response.addCookie(myCookie);
060: * </pre></code>
061: */
062: public class Cookie implements Cloneable {
063: private String key;
064: private String value;
065: private String comment;
066: private int maxAge = -1;
067: private String path;
068: private boolean secure;
069: private String name;
070: private String domain;
071: private int version = 0;
072:
073: /**
074: * Create a new cookie with the specified name and value.
075: *
076: * @param name name of the cookie
077: * @param value value of the cookie
078: */
079: public Cookie(String name, String value) {
080: int length = name.length();
081:
082: for (int i = length - 1; i >= 0; i--) {
083: char ch = name.charAt(i);
084:
085: if (ch >= 0x7f || !validChar[ch])
086: throw new IllegalArgumentException(
087: "illegal cookie name: " + name);
088:
089: else if (ch == '$' && i == 0)
090: throw new IllegalArgumentException(
091: "cookie can't start with '$'");
092: }
093:
094: this .name = name;
095: this .value = value;
096: }
097:
098: /**
099: * Sets the cookie comment
100: *
101: * @param comment comment string
102: */
103: public void setComment(String comment) {
104: this .comment = comment;
105: }
106:
107: /**
108: * Gets the cookie comment
109: */
110: public String getComment() {
111: return comment;
112: }
113:
114: /**
115: * Sets the cookie domain. A site which uses multiple machines, e.g.
116: * with DNS round robin, but a single site will want to set the domain.
117: *
118: * <code><pre>
119: * cookie.setDomain("yahoo.com");
120: * </pre></code>
121: *
122: * @param domain DNS domain name
123: */
124: public void setDomain(String domain) {
125: this .domain = domain;
126: }
127:
128: /**
129: * Returns the cookie's domain
130: */
131: public String getDomain() {
132: return domain;
133: }
134:
135: /**
136: * Sets the max age of a cookie. Setting <code>maxAge</code> to zero
137: * deletes the cookie. Setting it to something large makes the cookie
138: * persistent. If <code>maxAge</code> is not set, the cookie will only
139: * last for the session.
140: *
141: * @param maxAge lifetime of the cookie in seconds.
142: */
143: public void setMaxAge(int maxAge) {
144: this .maxAge = maxAge;
145: }
146:
147: /**
148: * Returns the max age of the cookie in seconds.
149: */
150: public int getMaxAge() {
151: return maxAge;
152: }
153:
154: /**
155: * Sets the URL path of a cookie. Normally, cookies will just use
156: * the root path.
157: */
158: public void setPath(String path) {
159: this .path = path;
160: }
161:
162: /**
163: * Gets the URL path of a cookie.
164: */
165: public String getPath() {
166: return path;
167: }
168:
169: /**
170: * Tells the browser that this cookie should only be passed over a
171: * secure connection like SSL.
172: */
173: public void setSecure(boolean secure) {
174: this .secure = secure;
175: }
176:
177: /**
178: * Returns true if the cookie must be over a secure connection.
179: */
180: public boolean getSecure() {
181: return secure;
182: }
183:
184: /**
185: * Returns the cookie's name.
186: */
187: public String getName() {
188: return name;
189: }
190:
191: /**
192: * Sets the cookie's value. Normally this will be a random unique
193: * string to lookup the cookie in a database.
194: */
195: public void setValue(String value) {
196: this .value = value;
197: }
198:
199: /**
200: * Returns the cookie's value.
201: */
202: public String getValue() {
203: return value;
204: }
205:
206: /**
207: * Returns cookie protocol version.
208: */
209: public int getVersion() {
210: return version;
211: }
212:
213: /**
214: * Sets cookie protocol version, defaulting to 0.
215: */
216: public void setVersion(int version) {
217: this .version = version;
218: }
219:
220: /**
221: * Returns a clone of the cookie
222: */
223: public Object clone() {
224: try {
225: return super .clone();
226: } catch (CloneNotSupportedException e) {
227: throw new RuntimeException(e.getMessage());
228: }
229: }
230:
231: /**
232: * Converts the cookie to a string for debugging.
233: */
234: public String toString() {
235: StringBuffer sb = new StringBuffer();
236: sb.append("[Cookie " + name + "=" + value);
237: if (path != null)
238: sb.append(" path=" + path);
239: if (domain != null)
240: sb.append(" domain=" + domain);
241: if (maxAge > 0)
242: sb.append(" max-age=" + maxAge);
243: if (secure)
244: sb.append(" secure");
245: sb.append("]");
246: return sb.toString();
247: }
248:
249: private static boolean[] validChar;
250:
251: static {
252: validChar = new boolean[128];
253: for (int i = 33; i < 127; i++)
254: validChar[i] = true;
255: validChar[','] = false;
256: validChar[';'] = false;
257: /*
258: * Disabled to match jakarta
259: *
260: validChar['('] = false;
261: validChar[')'] = false;
262: validChar['<'] = false;
263: validChar['>'] = false;
264: validChar['@'] = false;
265: validChar[':'] = false;
266: validChar['\\'] = false;
267: validChar['"'] = false;
268: validChar['/'] = false;
269: validChar['['] = false;
270: validChar[']'] = false;
271: validChar['?'] = false;
272: validChar['='] = false;
273: validChar['{'] = false;
274: validChar['}'] = false;
275: */
276: }
277: }
|