KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > terracotta > session > util > DefaultCookieWriter


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.terracotta.session.util;
5
6 import com.terracotta.session.SessionId;
7
8 import java.io.IOException JavaDoc;
9 import java.net.MalformedURLException JavaDoc;
10 import java.net.URL JavaDoc;
11 import java.net.URLEncoder JavaDoc;
12
13 import javax.servlet.http.Cookie JavaDoc;
14 import javax.servlet.http.HttpServletRequest JavaDoc;
15 import javax.servlet.http.HttpServletResponse JavaDoc;
16 import javax.servlet.http.HttpSession JavaDoc;
17
18 public class DefaultCookieWriter implements SessionCookieWriter {
19
20   protected static final int HTTP_PORT = 80;
21   protected static final int HTTPS_PORT = 443;
22
23   protected final String JavaDoc cookieName;
24   protected final String JavaDoc idTag;
25   private final boolean isTrackingEnabled;
26   private final boolean isCookieEnabled;
27   private final boolean isUrlRewriteEnabled;
28   private final String JavaDoc cookieDomain;
29   private final String JavaDoc cookiePath;
30   private final String JavaDoc cookieComment;
31   private final int cookieMaxAge;
32   private final boolean isCookieSecure;
33
34   public static DefaultCookieWriter makeInstance(ConfigProperties cp) {
35     Assert.pre(cp != null);
36     return new DefaultCookieWriter(cp.getSessionTrackingEnabled(), cp.getCookiesEnabled(), cp.getUrlRewritingEnabled(), cp.getCookieName(), cp.getCookieDomain(), cp.getCookiePath(), cp.getCookieCoomment(),
37          cp.getCookieMaxAgeSeconds(), cp.getCookieSecure());
38   }
39
40   protected DefaultCookieWriter(boolean isTrackingEnabled, boolean isCookieEnabled, boolean isUrlRewriteEnabled,
41                              String JavaDoc cookieName, String JavaDoc cookieDomain, String JavaDoc cookiePath, String JavaDoc cookieComment,
42                              int cookieMaxAge, boolean isCookieSecure) {
43     Assert.pre(cookieName != null && cookieName.trim().length() > 0);
44     Assert.pre(cookieMaxAge >= -1);
45     this.isTrackingEnabled = isTrackingEnabled;
46     this.isCookieEnabled = isCookieEnabled;
47     this.isUrlRewriteEnabled = isUrlRewriteEnabled;
48     this.cookieName = cookieName;
49     this.cookiePath = cookiePath;
50     this.cookieDomain = cookieDomain;
51     this.cookieComment = cookieComment;
52     this.cookieMaxAge = cookieMaxAge;
53     this.isCookieSecure = isCookieSecure;
54     this.idTag = ";" + this.cookieName.toLowerCase() + "=";
55   }
56
57   public void writeCookie(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res, SessionId id) {
58     Assert.pre(req != null);
59     Assert.pre(res != null);
60     Assert.pre(id != null);
61     
62     if (isTrackingEnabled && isCookieEnabled) res.addCookie(createCookie(req, res, id));
63   }
64
65   public String JavaDoc encodeRedirectURL(String JavaDoc url, HttpServletRequest JavaDoc req) {
66     Assert.pre(req!=null);
67     
68     if (url == null || !isTrackingEnabled || !isUrlRewriteEnabled) return url;
69     final String JavaDoc absolute = toAbsolute(url, req);
70     if (isEncodeable(absolute, req)) {
71       return toEncoded(url, req.getSession().getId(), idTag);
72     } else {
73       return url;
74     }
75   }
76
77   public String JavaDoc encodeURL(String JavaDoc url, HttpServletRequest JavaDoc req) {
78     Assert.pre(req != null);
79     
80     if (url == null || !isTrackingEnabled || !isUrlRewriteEnabled) return url;
81     String JavaDoc absolute = toAbsolute(url, req);
82     if (isEncodeable(absolute, req)) {
83       // W3c spec clearly said
84
if (url.equalsIgnoreCase("")) {
85         url = absolute;
86       }
87       return toEncoded(url, req.getSession().getId(), idTag);
88     } else {
89       return url;
90     }
91   }
92
93   private static String JavaDoc toEncoded(final String JavaDoc url, final String JavaDoc sessionId, final String JavaDoc idTag) {
94     Assert.pre(idTag != null);
95     
96     if ((url == null) || (sessionId == null)) return url;
97
98     String JavaDoc path = url;
99     String JavaDoc query = "";
100     String JavaDoc anchor = "";
101     int question = url.indexOf('?');
102     if (question >= 0) {
103       path = url.substring(0, question);
104       query = url.substring(question);
105     }
106     int pound = path.indexOf('#');
107     if (pound >= 0) {
108       anchor = path.substring(pound);
109       path = path.substring(0, pound);
110     }
111     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(path);
112     if (sb.length() > 0) { // jsessionid can't be first.
113
sb.append(idTag);
114       sb.append(sessionId);
115     }
116     sb.append(anchor);
117     sb.append(query);
118     return sb.toString();
119   }
120
121   protected static boolean isEncodeable(final String JavaDoc location, final HttpServletRequest JavaDoc hreq) {
122
123     Assert.pre(hreq != null);
124     
125     if (location == null) return false;
126
127     // Is this an intra-document reference?
128
if (location.startsWith("#")) return false;
129
130     final HttpSession JavaDoc session = hreq.getSession(false);
131     if (session == null) return false;
132     if (hreq.isRequestedSessionIdFromCookie()) return false;
133
134     return isEncodeable(hreq, session, location);
135   }
136
137   private static boolean isEncodeable(HttpServletRequest JavaDoc hreq, HttpSession JavaDoc session, String JavaDoc location) {
138     Assert.pre(hreq != null);
139     Assert.pre(session != null);
140     
141     // Is this a valid absolute URL?
142
URL JavaDoc url = null;
143     try {
144       url = new URL JavaDoc(location);
145     } catch (MalformedURLException JavaDoc e) {
146       return false;
147     }
148
149     // Does this URL match down to (and including) the context path?
150
if (!hreq.getScheme().equalsIgnoreCase(url.getProtocol())) return false;
151     if (!hreq.getServerName().equalsIgnoreCase(url.getHost())) return false;
152     final int serverPort = getPort(hreq);
153     int urlPort = getPort(url);
154     if (serverPort != urlPort) return false;
155
156     String JavaDoc contextPath = hreq.getContextPath();
157     if (contextPath != null) {
158       String JavaDoc file = url.getFile();
159       if ((file == null) || !file.startsWith(contextPath)) return false;
160       if (file.indexOf(";jsessionid=" + session.getId()) >= 0) return false;
161     }
162
163     // This URL belongs to our web application, so it is encodeable
164
return true;
165
166   }
167
168   private static int getPort(URL JavaDoc url) {
169     Assert.pre(url != null);
170     return getPort(url.getPort(), url.getProtocol());
171   }
172
173   private static int getPort(HttpServletRequest JavaDoc hreq) {
174     Assert.pre(hreq != null);
175     return getPort(hreq.getServerPort(), hreq.getScheme());
176   }
177
178   private static int getPort(final int port, final String JavaDoc scheme) {
179     if (port == -1) {
180       if ("https".equals(scheme)) return 443;
181       else return 80;
182     }
183     return port;
184   }
185
186   private static String JavaDoc toAbsolute(String JavaDoc location, HttpServletRequest JavaDoc request) {
187     Assert.pre(request != null);
188     if (location == null) return location;
189
190     final boolean leadingSlash = location.startsWith("/");
191
192     if (leadingSlash || (!leadingSlash && (location.indexOf("://") == -1))) {
193       final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
194
195       final String JavaDoc scheme = request.getScheme();
196       final String JavaDoc name = request.getServerName();
197       final int port = request.getServerPort();
198
199       sb.append(scheme);
200       sb.append("://");
201       sb.append(name);
202       sb.append(getPortString(scheme, port));
203       if (!leadingSlash) {
204         final String JavaDoc relativePath = request.getRequestURI();
205         final int pos = relativePath.lastIndexOf('/');
206         final String JavaDoc frelativePath = relativePath.substring(0, pos);
207         sb.append(encodeSafely(frelativePath));
208         sb.append('/');
209       }
210       sb.append(location);
211       return sb.toString();
212     } else {
213       return location;
214     }
215   }
216
217   private static String JavaDoc getPortString(final String JavaDoc scheme, final int port) {
218     if (("http".equals(scheme) && port != 80) || ("https".equals(scheme) && port != 443)) {
219       return ":" + port;
220     } else {
221       return "";
222     }
223   }
224
225   private static String JavaDoc encodeSafely(final String JavaDoc source) {
226     try {
227       return URLEncoder.encode(source, "UTF-8");
228     } catch (IOException JavaDoc e) {
229       return source;
230     }
231   }
232
233   protected Cookie JavaDoc createCookie(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res, SessionId id) {
234     Assert.pre(req != null);
235     Assert.pre(res != null);
236     Assert.pre(id != null);
237     
238     Cookie JavaDoc c = new Cookie JavaDoc(cookieName, id.getExternalId());
239     c.setPath(getCookiePath(req));
240     c.setMaxAge(cookieMaxAge);
241     c.setSecure(isCookieSecure);
242     if (cookieDomain != null) c.setDomain(cookieDomain);
243     if (cookieComment != null) c.setComment(cookieComment);
244
245     Assert.post(c != null);
246     return c;
247   }
248
249   protected String JavaDoc getCookiePath(HttpServletRequest JavaDoc req) {
250     Assert.pre(req != null);
251     if (cookiePath == null) {
252       // if nothing is specified, use request context path
253
String JavaDoc rv = req.getContextPath();
254       return rv == null || rv.trim().length() == 0 ? ConfigProperties.defaultCookiePath : rv.trim();
255     } else {
256       return cookiePath;
257     }
258   }
259 }
260
Popular Tags