1 /*
2 * ========================================================================
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * ========================================================================
20 */
21 package org.apache.cactus;
22
23 import java.io.Serializable;
24
25 import java.util.Date;
26
27 import org.apache.cactus.internal.util.CookieUtil;
28
29 /**
30 * Client cookie. Used for manipulating client cookies either in
31 * <code>beginXXX()</code> (to send cookies) or in
32 * <code>endXXX()</code> methods (to assert returned cookies).
33 *
34 * @version $Id: Cookie.java 238991 2004-05-22 11:34:50Z vmassol $
35 */
36 public class Cookie implements Serializable
37 {
38 /**
39 * The cookie name.
40 */
41 private String name;
42
43 /**
44 * The cookie value.
45 */
46 private String value;
47
48 /**
49 * The cookie description.
50 * @see #setComment(String)
51 */
52 private String comment;
53
54 /**
55 * The cookie domain.
56 * @see #setDomain(String)
57 */
58 private String domain;
59
60 /**
61 * The cookie expiry date.
62 * @see #setExpiryDate(Date)
63 */
64 private Date expiryDate;
65
66 /**
67 * The cookie path.
68 * @see #setPath(String)
69 */
70 private String path;
71
72 /**
73 * True if the cookie should only be sent over secure connections.
74 * @see #setSecure(boolean)
75 */
76 private boolean isSecure = false;
77
78 /**
79 * Create a cookie.
80 *
81 * @param theDomain the cookie domain
82 * @param theName the cookie name
83 * @param theValue the cookie value
84 */
85 public Cookie(String theDomain, String theName, String theValue)
86 {
87 if (theDomain == null)
88 {
89 throw new NullPointerException("missing cookie domain");
90 }
91
92 if (theName == null)
93 {
94 throw new NullPointerException("missing cookie name");
95 }
96
97 if (theValue == null)
98 {
99 throw new NullPointerException("missing cookie value");
100 }
101
102 setDomain(theDomain);
103 setName(theName);
104 setValue(theValue);
105 }
106
107 /**
108 * Sets the cookie name.
109 *
110 * @param theName the cookie name
111 */
112 public void setName(String theName)
113 {
114 this.name = theName;
115 }
116
117 /**
118 * @return the cookie name.
119 */
120 public String getName()
121 {
122 return this.name;
123 }
124
125 /**
126 * Sets the cookie value.
127 *
128 * @param theValue the cookie value
129 */
130 public void setValue(String theValue)
131 {
132 this.value = theValue;
133 }
134
135 /**
136 * @return the cookie value
137 */
138 public String getValue()
139 {
140 return this.value;
141 }
142
143 /**
144 * Returns the comment describing the purpose of this cookie, or
145 * null if no such comment has been defined.
146 *
147 * @return the cookie comment
148 */
149 public String getComment()
150 {
151 return this.comment;
152 }
153
154 /**
155 * If a user agent (web browser) presents this cookie to a user, the
156 * cookie's purpose will be described using this comment.
157 *
158 * @param theComment the cookie's text comment
159 */
160 public void setComment(String theComment)
161 {
162 this.comment = theComment;
163 }
164
165 /**
166 * Return the expiry date.
167 *
168 * @return the expiry date of this cookie, or null if none set.
169 */
170 public Date getExpiryDate()
171 {
172 return this.expiryDate;
173 }
174
175 /**
176 * Set the cookie expires date.
177 *
178 * <p>Netscape's original proposal defined an Expires header that took
179 * a date value in a fixed-length variant format in place of Max-Age:
180 *
181 * Wdy, DD-Mon-YY HH:MM:SS GMT
182 *
183 * Note that the Expires date format contains embedded spaces, and that
184 * "old" cookies did not have quotes around values. Clients that
185 * implement to this specification should be aware of "old" cookies and
186 * Expires.
187 *
188 * @param theExpiryDate the expires date.
189 */
190 public void setExpiryDate(Date theExpiryDate)
191 {
192 this.expiryDate = theExpiryDate;
193 }
194
195 /**
196 * @return true if the cookie should be discarded at the end of the
197 * session; false otherwise
198 */
199 public boolean isToBeDiscarded()
200 {
201 return (this.getExpiryDate() != null);
202 }
203
204 /**
205 * Returns the domain of this cookie.
206 *
207 * @return the cookie domain
208 */
209 public String getDomain()
210 {
211 return this.domain;
212 }
213
214 /**
215 * Sets the cookie domain. This cookie should be presented only to hosts
216 * satisfying this domain name pattern. Read RFC 2109 for specific
217 * details of the syntax.
218 *
219 * Briefly, a domain name name begins with a dot (".foo.com") and means
220 * that hosts in that DNS zone ("www.foo.com", but not "a.b.foo.com")
221 * should see the cookie. By default, cookies are only returned to
222 * the host which saved them.
223 *
224 * @param theDomain the cookie domain
225 */
226 public void setDomain(String theDomain)
227 {
228 int ndx = theDomain.indexOf(":");
229
230 if (ndx != -1)
231 {
232 theDomain = theDomain.substring(0, ndx);
233 }
234
235 this.domain = theDomain.toLowerCase();
236 }
237
238 /**
239 * Return the path this cookie is associated with.
240 *
241 * @return the cookie path
242 */
243 public String getPath()
244 {
245 return this.path;
246 }
247
248 /**
249 * Sets the cookie path. This cookie should be presented only with
250 * requests beginning with this URL. Read RFC 2109 for a specification
251 * of the default behaviour. Basically, URLs in the same "directory" as
252 * the one which set the cookie, and in subdirectories, can all see the
253 * cookie unless a different path is set.
254 *
255 * @param thePath the cookie path
256 */
257 public void setPath(String thePath)
258 {
259 this.path = thePath;
260 }
261
262 /**
263 * @return true if the cookie should only be sent over secure connections.
264 */
265 public boolean isSecure()
266 {
267 return this.isSecure;
268 }
269
270 /**
271 * Indicates to the user agent that the cookie should only be sent
272 * using a secure protocol (https). This should only be set when
273 * the cookie's originating server used a secure protocol to set the
274 * cookie's value.
275 *
276 * @param isSecure true if the cookie should be sent over secure
277 * connections only
278 */
279 public void setSecure(boolean isSecure)
280 {
281 this.isSecure = isSecure;
282 }
283
284 /**
285 * @return true if this cookie has expired
286 */
287 public boolean isExpired()
288 {
289 return (this.getExpiryDate() != null
290 && this.getExpiryDate().getTime() <= System.currentTimeMillis());
291 }
292
293 /**
294 * Hash up name, value and domain into new hash.
295 *
296 * @return the hashcode of this class
297 */
298 public int hashCode()
299 {
300 return (this.getName().hashCode() + this.getValue().hashCode()
301 + this.getDomain().hashCode());
302 }
303
304 /**
305 * Two cookies match if the name, path and domain match.
306 *
307 * @param theObject the cookie object to match
308 * @return true of the object passed as paramater is equal to this coookie
309 * instance
310 */
311 public boolean equals(Object theObject)
312 {
313 if ((theObject != null) && (theObject instanceof Cookie))
314 {
315 Cookie other = (Cookie) theObject;
316
317 return (this.getName().equals(other.getName())
318 && this.getPath().equals(other.getPath())
319 && this.getDomain().equals(other.getDomain()));
320 }
321
322 return false;
323 }
324
325 /**
326 * @return a string representation of the cookie
327 */
328 public String toString()
329 {
330 StringBuffer buffer = new StringBuffer();
331
332 buffer.append("name = [" + getName() + "], ");
333 buffer.append("value = [" + getValue() + "], ");
334 buffer.append("domain = [" + getDomain() + "], ");
335 buffer.append("path = [" + getPath() + "], ");
336 buffer.append("isSecure = [" + isSecure() + "], ");
337 buffer.append("comment = [" + getComment() + "], ");
338 buffer.append("expiryDate = [" + getExpiryDate() + "]");
339
340 return buffer.toString();
341 }
342
343 /**
344 * @see CookieUtil#getCookieDomain(WebRequest, String)
345 * @param theRequest from which to derive the domain
346 * @param theRealHost of the cookie
347 * @return String
348 * @deprecated use {@link CookieUtil#getCookieDomain(WebRequest, String)}
349 */
350 public static String getCookieDomain(WebRequest theRequest,
351 String theRealHost)
352 {
353 return CookieUtil.getCookieDomain(theRequest, theRealHost);
354 }
355
356 /**
357 * @see CookieUtil#getCookiePort(WebRequest, int)
358 * @param theRequest from which to derive the port
359 * @param theRealPort of the cookie
360 * @return int
361 * @deprecated use {@link CookieUtil#getCookiePort(WebRequest, int)}
362 */
363 public static int getCookiePort(WebRequest theRequest, int theRealPort)
364 {
365 return CookieUtil.getCookiePort(theRequest, theRealPort);
366 }
367
368 /**
369 * @see CookieUtil#getCookiePath(WebRequest, String)
370 * @param theRequest from from which to derive the path
371 * @param theRealPath of the cookie
372 * @return String
373 * @deprecated use {@link CookieUtil#getCookiePath(WebRequest, String)}
374 */
375 public static String getCookiePath(WebRequest theRequest,
376 String theRealPath)
377 {
378 return CookieUtil.getCookiePath(theRequest, theRealPath);
379 }
380 }