KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tomcat > util > http > ServerCookie


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.tomcat.util.http;
19
20 import java.io.Serializable JavaDoc;
21 import java.text.FieldPosition JavaDoc;
22 import java.util.Date JavaDoc;
23
24 import org.apache.tomcat.util.buf.DateTool;
25 import org.apache.tomcat.util.buf.MessageBytes;
26
27
28 /**
29  * Server-side cookie representation.
30  * Allows recycling and uses MessageBytes as low-level
31  * representation ( and thus the byte-> char conversion can be delayed
32  * until we know the charset ).
33  *
34  * Tomcat.core uses this recyclable object to represent cookies,
35  * and the facade will convert it to the external representation.
36  */

37 public class ServerCookie implements Serializable JavaDoc {
38     
39     
40     private static org.apache.commons.logging.Log log=
41         org.apache.commons.logging.LogFactory.getLog(ServerCookie.class );
42     
43     private MessageBytes name=MessageBytes.newInstance();
44     private MessageBytes value=MessageBytes.newInstance();
45
46     private MessageBytes comment=MessageBytes.newInstance(); // ;Comment=VALUE
47
private MessageBytes domain=MessageBytes.newInstance(); // ;Domain=VALUE ...
48

49     private int maxAge = -1; // ;Max-Age=VALUE
50
// ;Discard ... implied by maxAge < 0
51
// RFC2109: maxAge=0 will end a session
52
private MessageBytes path=MessageBytes.newInstance(); // ;Path=VALUE .
53
private boolean secure; // ;Secure
54
private int version = 0; // ;Version=1
55

56     //XXX CommentURL, Port -> use notes ?
57

58     public ServerCookie() {
59
60     }
61
62     public void recycle() {
63         path.recycle();
64         name.recycle();
65         value.recycle();
66         comment.recycle();
67         maxAge=-1;
68         path.recycle();
69         domain.recycle();
70         version=0;
71         secure=false;
72     }
73
74     public MessageBytes getComment() {
75     return comment;
76     }
77
78     public MessageBytes getDomain() {
79     return domain;
80     }
81
82     public void setMaxAge(int expiry) {
83     maxAge = expiry;
84     }
85
86     public int getMaxAge() {
87     return maxAge;
88     }
89
90
91     public MessageBytes getPath() {
92     return path;
93     }
94
95     public void setSecure(boolean flag) {
96     secure = flag;
97     }
98
99     public boolean getSecure() {
100     return secure;
101     }
102
103     public MessageBytes getName() {
104     return name;
105     }
106
107     public MessageBytes getValue() {
108     return value;
109     }
110
111     public int getVersion() {
112     return version;
113     }
114
115
116     public void setVersion(int v) {
117     version = v;
118     }
119
120
121     // -------------------- utils --------------------
122

123     public String JavaDoc toString() {
124     return "Cookie " + getName() + "=" + getValue() + " ; "
125         + getVersion() + " " + getPath() + " " + getDomain();
126     }
127     
128     // Note -- disabled for now to allow full Netscape compatibility
129
// from RFC 2068, token special case characters
130
//
131
// private static final String tspecials = "()<>@,;:\\\"/[]?={} \t";
132
private static final String JavaDoc tspecials = ",; ";
133
134     /*
135      * Tests a string and returns true if the string counts as a
136      * reserved token in the Java language.
137      *
138      * @param value the <code>String</code> to be tested
139      *
140      * @return <code>true</code> if the <code>String</code> is
141      * a reserved token; <code>false</code>
142      * if it is not
143      */

144     public static boolean isToken(String JavaDoc value) {
145     if( value==null) return true;
146     int len = value.length();
147
148     for (int i = 0; i < len; i++) {
149         char c = value.charAt(i);
150
151         if (c < 0x20 || c >= 0x7f || tspecials.indexOf(c) != -1)
152         return false;
153     }
154     return true;
155     }
156
157     public static boolean checkName( String JavaDoc name ) {
158     if (!isToken(name)
159         || name.equalsIgnoreCase("Comment") // rfc2019
160
|| name.equalsIgnoreCase("Discard") // 2019++
161
|| name.equalsIgnoreCase("Domain")
162         || name.equalsIgnoreCase("Expires") // (old cookies)
163
|| name.equalsIgnoreCase("Max-Age") // rfc2019
164
|| name.equalsIgnoreCase("Path")
165         || name.equalsIgnoreCase("Secure")
166         || name.equalsIgnoreCase("Version")
167         ) {
168         return false;
169     }
170     return true;
171     }
172
173     // -------------------- Cookie parsing tools
174

175     
176     /** Return the header name to set the cookie, based on cookie
177      * version
178      */

179     public String JavaDoc getCookieHeaderName() {
180     return getCookieHeaderName(version);
181     }
182
183     /** Return the header name to set the cookie, based on cookie
184      * version
185      */

186     public static String JavaDoc getCookieHeaderName(int version) {
187     if( dbg>0 ) log( (version==1) ? "Set-Cookie2" : "Set-Cookie");
188         if (version == 1) {
189         // RFC2109
190
return "Set-Cookie";
191         // XXX RFC2965 is not standard yet, and Set-Cookie2
192
// is not supported by Netscape 4, 6, IE 3, 5 .
193
// It is supported by Lynx, and there is hope
194
// return "Set-Cookie2";
195
} else {
196         // Old Netscape
197
return "Set-Cookie";
198         }
199     }
200
201     private static final String JavaDoc ancientDate=DateTool.formatOldCookie(new Date JavaDoc(10000));
202
203     public static void appendCookieValue( StringBuffer JavaDoc buf,
204                       int version,
205                       String JavaDoc name,
206                       String JavaDoc value,
207                       String JavaDoc path,
208                       String JavaDoc domain,
209                       String JavaDoc comment,
210                       int maxAge,
211                       boolean isSecure )
212     {
213         // this part is the same for all cookies
214
buf.append( name );
215         buf.append("=");
216         maybeQuote(version, buf, value);
217
218     // XXX Netscape cookie: "; "
219
// add version 1 specific information
220
if (version == 1) {
221         // Version=1 ... required
222
buf.append ("; Version=1");
223
224         // Comment=comment
225
if ( comment!=null ) {
226         buf.append ("; Comment=");
227         maybeQuote (version, buf, comment);
228         }
229     }
230     
231     // add domain information, if present
232

233     if (domain!=null) {
234         buf.append("; Domain=");
235         maybeQuote (version, buf, domain);
236     }
237
238     // Max-Age=secs/Discard ... or use old "Expires" format
239
if (maxAge >= 0) {
240         if (version == 0) {
241         // XXX XXX XXX We need to send both, for
242
// interoperatibility (long word )
243
buf.append ("; Expires=");
244         // Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires netscape format )
245
// To expire we need to set the time back in future
246
// ( pfrieden@dChain.com )
247
if (maxAge == 0)
248             buf.append( ancientDate );
249         else
250                     DateTool.formatOldCookie
251                         (new Date JavaDoc( System.currentTimeMillis() +
252                                    maxAge *1000L), buf,
253                          new FieldPosition JavaDoc(0));
254
255         } else {
256         buf.append ("; Max-Age=");
257         buf.append (maxAge);
258         }
259     }
260
261     // Path=path
262
if (path!=null) {
263         buf.append ("; Path=");
264         maybeQuote (version, buf, path);
265     }
266
267     // Secure
268
if (isSecure) {
269       buf.append ("; Secure");
270     }
271     
272     
273     }
274
275     public static void maybeQuote (int version, StringBuffer JavaDoc buf,
276             String JavaDoc value) {
277         // special case - a \n or \r shouldn't happen in any case
278
if (isToken(value)) {
279             buf.append(value);
280         } else {
281             buf.append('"');
282             buf.append(escapeDoubleQuotes(value));
283             buf.append('"');
284         }
285     }
286
287     // log
288
static final int dbg=1;
289     public static void log(String JavaDoc s ) {
290         if (log.isDebugEnabled())
291             log.debug("ServerCookie: " + s);
292     }
293
294
295     /**
296      * Escapes any double quotes in the given string.
297      *
298      * @param s the input string
299      *
300      * @return The (possibly) escaped string
301      */

302     private static String JavaDoc escapeDoubleQuotes(String JavaDoc s) {
303
304         if (s == null || s.length() == 0 || s.indexOf('"') == -1) {
305             return s;
306         }
307
308         StringBuffer JavaDoc b = new StringBuffer JavaDoc();
309         for (int i = 0; i < s.length(); i++) {
310             char c = s.charAt(i);
311             if (c == '"')
312                 b.append('\\').append('"');
313             else
314                 b.append(c);
315         }
316
317         return b.toString();
318     }
319
320 }
321
322
Popular Tags