1 16 package org.directwebremoting.servlet; 17 18 import java.io.BufferedReader ; 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.io.InputStreamReader ; 22 import java.io.PrintWriter ; 23 import java.util.HashMap ; 24 import java.util.Map ; 25 26 import javax.servlet.http.HttpServletRequest ; 27 import javax.servlet.http.HttpServletResponse ; 28 29 import org.directwebremoting.extend.DwrConstants; 30 import org.directwebremoting.extend.Handler; 31 import org.directwebremoting.util.IdGenerator; 32 import org.directwebremoting.util.JavascriptUtil; 33 import org.directwebremoting.util.LocalUtil; 34 import org.directwebremoting.util.Logger; 35 import org.directwebremoting.util.MimeConstants; 36 37 42 public class FileHandler implements Handler 43 { 44 50 public FileHandler(String filePath, String mimeType, boolean dynamic) 51 { 52 this.filePath = filePath; 53 this.mimeType = mimeType; 54 this.dynamic = dynamic; 55 } 56 57 60 public FileHandler() 61 { 62 } 63 64 67 public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException 68 { 69 if (dynamic) 70 { 71 response.setHeader("pragma", "public"); 72 response.setHeader("Expires", "0"); 73 response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); 74 } 75 76 if (!dynamic && isUpToDate(request)) 77 { 78 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); 79 return; 80 } 81 82 String output; 83 84 synchronized (scriptCache) 85 { 86 output = (String ) scriptCache.get(filePath); 87 if (output == null) 88 { 89 StringBuffer buffer = new StringBuffer (); 90 91 String resource = DwrConstants.PACKAGE + filePath; 92 InputStream raw = getClass().getResourceAsStream(resource); 93 if (raw == null) 94 { 95 throw new IOException ("Failed to find resource: " + resource); 96 } 97 98 BufferedReader in = new BufferedReader (new InputStreamReader (raw)); 99 while (true) 100 { 101 String line = in.readLine(); 102 if (line == null) 103 { 104 break; 105 } 106 107 if (dynamic) 108 { 109 if (line.indexOf(PARAM_SCRIPT_COOKIENAME) != -1) 110 { 111 line = LocalUtil.replace(line, PARAM_SCRIPT_COOKIENAME, sessionCookieName); 112 } 113 114 if (line.indexOf(PARAM_SCRIPT_SESSIONID) != -1) 115 { 116 line = LocalUtil.replace(line, PARAM_SCRIPT_SESSIONID, generator.generateId(pageIdLength)); 117 } 118 119 if (line.indexOf(PARAM_SCRIPT_ALLOWGET) != -1) 120 { 121 line = LocalUtil.replace(line, PARAM_SCRIPT_ALLOWGET, String.valueOf(allowGetForSafariButMakeForgeryEasier)); 122 } 123 124 if (line.indexOf(PARAM_SCRIPT_TAG_PROTECTION) != -1) 125 { 126 line = LocalUtil.replace(line, PARAM_SCRIPT_TAG_PROTECTION, scriptTagProtection); 127 } 128 129 if (line.indexOf(PARAM_DEFAULT_PATH) != -1) 130 { 131 String path = request.getContextPath() + request.getServletPath(); 132 if (overridePath != null) 133 { 134 path = overridePath; 135 } 136 line = LocalUtil.replace(line, PARAM_DEFAULT_PATH, path); 137 } 138 } 139 140 buffer.append(line); 141 buffer.append('\n'); 142 } 143 144 output = buffer.toString(); 145 146 if (mimeType.equals(MimeConstants.MIME_JS) && scriptCompressed) 147 { 148 output = JavascriptUtil.compress(output, compressionLevel); 149 } 150 151 if (!dynamic) 152 { 153 scriptCache.put(filePath, output); 154 } 155 } 156 } 157 158 response.setContentType(mimeType); 159 response.setDateHeader(HttpConstants.HEADER_LAST_MODIFIED, servletContainerStartTime); 160 response.setHeader(HttpConstants.HEADER_ETAG, etag); 161 162 PrintWriter out = response.getWriter(); 163 out.println(output); 164 } 165 166 171 private boolean isUpToDate(HttpServletRequest req) 172 { 173 if (ignoreLastModified) 174 { 175 return false; 176 } 177 178 long modifiedSince = -1; 179 try 180 { 181 modifiedSince = req.getDateHeader(HttpConstants.HEADER_IF_MODIFIED); 183 } 184 catch (RuntimeException ex) 185 { 186 } 197 198 if (modifiedSince != -1) 199 { 200 modifiedSince -= modifiedSince % 1000; 202 } 203 String givenEtag = req.getHeader(HttpConstants.HEADER_IF_NONE); 204 205 if (givenEtag == null) 207 { 208 if (modifiedSince > servletContainerStartTime) 210 { 211 if (log.isDebugEnabled()) 212 { 213 log.debug("Sending 304 for " + filePath + " If-Modified-Since=" + modifiedSince + ", Last-Modified=" + servletContainerStartTime); 214 } 215 return true; 216 } 217 218 return false; 220 } 221 222 if (modifiedSince == -1) 224 { 225 if (!etag.equals(givenEtag)) 226 { 227 if (log.isDebugEnabled()) 229 { 230 log.debug("Sending 304 for " + filePath + " Old ETag=" + givenEtag + ", New ETag=" + etag); 231 } 232 return true; 233 } 234 235 return false; 237 } 238 239 if (etag.equals(givenEtag) && modifiedSince <= servletContainerStartTime) 241 { 242 if (log.isDebugEnabled()) 243 { 244 log.debug("Sending 304 for " + filePath); 245 } 246 return true; 247 } 248 249 return false; 250 } 251 252 255 public void setAllowGetForSafariButMakeForgeryEasier(boolean allowGetForSafariButMakeForgeryEasier) 256 { 257 this.allowGetForSafariButMakeForgeryEasier = allowGetForSafariButMakeForgeryEasier; 258 } 259 260 263 public void setIgnoreLastModified(boolean ignoreLastModified) 264 { 265 this.ignoreLastModified = ignoreLastModified; 266 } 267 268 272 public void setSessionCookieName(String sessionCookieName) 273 { 274 this.sessionCookieName = sessionCookieName; 275 } 276 277 281 public void setScriptCompressed(boolean scriptCompressed) 282 { 283 this.scriptCompressed = scriptCompressed; 284 } 285 286 289 public void setCompressionLevel(int compressionLevel) 290 { 291 this.compressionLevel = compressionLevel; 292 } 293 294 297 public void setFilePath(String filePath) 298 { 299 this.filePath = filePath; 300 } 301 302 306 public void setDynamic(boolean dynamic) 307 { 308 this.dynamic = dynamic; 309 } 310 311 315 public void setMimeType(String mimeType) 316 { 317 this.mimeType = mimeType; 318 } 319 320 324 public void setScriptTagProtection(String scriptTagProtection) 325 { 326 this.scriptTagProtection = scriptTagProtection; 327 } 328 329 333 public void setOverridePath(String overridePath) 334 { 335 this.overridePath = overridePath; 336 } 337 338 341 private String overridePath = null; 342 343 346 private boolean allowGetForSafariButMakeForgeryEasier = false; 347 348 351 private String scriptTagProtection = DwrConstants.SCRIPT_TAG_PROTECTION; 352 353 356 protected boolean ignoreLastModified = false; 357 358 361 protected String sessionCookieName = "JSESSIONID"; 362 363 366 protected int compressionLevel = JavascriptUtil.LEVEL_DEBUGGABLE; 367 368 371 protected boolean scriptCompressed = false; 372 373 376 protected IdGenerator generator = new IdGenerator(); 377 378 381 protected int pageIdLength = 16; 382 383 386 protected final Map scriptCache = new HashMap (); 387 388 391 private String filePath; 392 393 396 private String mimeType; 397 398 401 private boolean dynamic; 402 403 406 private static final long servletContainerStartTime; 407 408 411 private static final String etag; 412 413 416 static 417 { 418 long now = System.currentTimeMillis(); 420 servletContainerStartTime = now - (now % 1000); 421 422 etag = "\"" + servletContainerStartTime + '\"'; 423 } 424 425 428 protected static final String PARAM_SCRIPT_ALLOWGET = "${allowGetForSafariButMakeForgeryEasier}"; 429 430 433 protected static final String PARAM_SCRIPT_SESSIONID = "${scriptSessionId}"; 434 435 438 protected static final String PARAM_SCRIPT_COOKIENAME = "${sessionCookieName}"; 439 440 444 protected static final String PARAM_SCRIPT_TAG_PROTECTION = "${scriptTagProtection}"; 445 446 450 protected static final String PARAM_DEFAULT_PATH = "${defaultPath}"; 451 452 455 private static final Logger log = Logger.getLogger(FileHandler.class); 456 } 457 | Popular Tags |