1 4 package com.terracotta.session.util; 5 6 import com.terracotta.session.SessionId; 7 8 import java.io.IOException ; 9 import java.net.MalformedURLException ; 10 import java.net.URL ; 11 import java.net.URLEncoder ; 12 13 import javax.servlet.http.Cookie ; 14 import javax.servlet.http.HttpServletRequest ; 15 import javax.servlet.http.HttpServletResponse ; 16 import javax.servlet.http.HttpSession ; 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 cookieName; 24 protected final String idTag; 25 private final boolean isTrackingEnabled; 26 private final boolean isCookieEnabled; 27 private final boolean isUrlRewriteEnabled; 28 private final String cookieDomain; 29 private final String cookiePath; 30 private final String 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 cookieName, String cookieDomain, String cookiePath, String 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 req, HttpServletResponse 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 encodeRedirectURL(String url, HttpServletRequest req) { 66 Assert.pre(req!=null); 67 68 if (url == null || !isTrackingEnabled || !isUrlRewriteEnabled) return url; 69 final String 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 encodeURL(String url, HttpServletRequest req) { 78 Assert.pre(req != null); 79 80 if (url == null || !isTrackingEnabled || !isUrlRewriteEnabled) return url; 81 String absolute = toAbsolute(url, req); 82 if (isEncodeable(absolute, req)) { 83 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 toEncoded(final String url, final String sessionId, final String idTag) { 94 Assert.pre(idTag != null); 95 96 if ((url == null) || (sessionId == null)) return url; 97 98 String path = url; 99 String query = ""; 100 String 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 sb = new StringBuffer (path); 112 if (sb.length() > 0) { 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 location, final HttpServletRequest hreq) { 122 123 Assert.pre(hreq != null); 124 125 if (location == null) return false; 126 127 if (location.startsWith("#")) return false; 129 130 final HttpSession 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 hreq, HttpSession session, String location) { 138 Assert.pre(hreq != null); 139 Assert.pre(session != null); 140 141 URL url = null; 143 try { 144 url = new URL (location); 145 } catch (MalformedURLException e) { 146 return false; 147 } 148 149 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 contextPath = hreq.getContextPath(); 157 if (contextPath != null) { 158 String 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 return true; 165 166 } 167 168 private static int getPort(URL url) { 169 Assert.pre(url != null); 170 return getPort(url.getPort(), url.getProtocol()); 171 } 172 173 private static int getPort(HttpServletRequest 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 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 toAbsolute(String location, HttpServletRequest 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 sb = new StringBuffer (); 194 195 final String scheme = request.getScheme(); 196 final String 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 relativePath = request.getRequestURI(); 205 final int pos = relativePath.lastIndexOf('/'); 206 final String 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 getPortString(final String 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 encodeSafely(final String source) { 226 try { 227 return URLEncoder.encode(source, "UTF-8"); 228 } catch (IOException e) { 229 return source; 230 } 231 } 232 233 protected Cookie createCookie(HttpServletRequest req, HttpServletResponse res, SessionId id) { 234 Assert.pre(req != null); 235 Assert.pre(res != null); 236 Assert.pre(id != null); 237 238 Cookie c = new Cookie (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 getCookiePath(HttpServletRequest req) { 250 Assert.pre(req != null); 251 if (cookiePath == null) { 252 String 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 |