1 4 5 9 10 package org.openlaszlo.servlets.responders; 11 12 import java.io.*; 13 import java.net.URL ; 14 import java.util.Hashtable ; 15 import java.util.Properties ; 16 import javax.servlet.ServletConfig ; 17 import javax.servlet.ServletOutputStream ; 18 import javax.servlet.ServletException ; 19 import javax.servlet.http.HttpUtils ; 20 import javax.servlet.http.HttpSession ; 21 import javax.servlet.http.HttpServletRequest ; 22 import javax.servlet.http.HttpServletResponse ; 23 import org.openlaszlo.cm.CompilationManager; 24 import org.openlaszlo.compiler.Canvas; 25 import org.openlaszlo.compiler.CompilationError; 26 import org.openlaszlo.compiler.CompilationEnvironment; 27 import org.openlaszlo.sc.ScriptCompiler; 28 import org.openlaszlo.utils.ContentEncoding; 29 import org.openlaszlo.utils.FileUtils; 30 import org.openlaszlo.utils.LZHttpUtils; 31 import org.openlaszlo.utils.LZGetMethod; 32 import org.openlaszlo.utils.StringUtils; 33 import org.openlaszlo.server.LPS; 34 import org.openlaszlo.servlets.LZBindingListener; 35 import org.apache.commons.httpclient.HttpClient; 36 import org.apache.commons.httpclient.methods.GetMethod; 37 38 import org.apache.log4j.Logger; 39 40 41 42 public abstract class ResponderCompile extends Responder 43 { 44 protected static CompilationManager mCompMgr = null; 45 protected static ScriptCompiler mScriptCache = null; 46 47 private static boolean mIsInitialized = false; 48 private static boolean mAllowRequestSOURCE = true; 49 private static boolean mAllowRequestKRANK = true; 50 private static boolean mAllowRecompile = true; 51 private static boolean mCheckModifiedSince = true; 52 private static String mAdminPassword = null; 53 private static Logger mLogger = Logger.getLogger(ResponderCompile.class); 54 55 57 abstract protected void respondImpl(String fileName, HttpServletRequest req, 58 HttpServletResponse res) 59 throws IOException; 60 61 62 synchronized public void init(String reqName, ServletConfig config, Properties prop) 63 throws ServletException , IOException 64 { 65 super.init(reqName, config, prop); 66 67 if (! mIsInitialized) { 69 70 mAllowRequestSOURCE = 71 prop.getProperty("allowRequestSOURCE", "true").intern() == "true"; 72 mAllowRequestKRANK = 73 prop.getProperty("allowRequestKRANK", "true").intern() == "true"; 74 mCheckModifiedSince = 75 prop.getProperty("checkModifiedSince", "true").intern() == "true"; 76 mAllowRecompile = 77 prop.getProperty("allowRecompile", "true").intern() == "true"; 78 79 mAdminPassword = prop.getProperty("adminPassword", null); 80 81 String cacheDir = config.getInitParameter("lps.cache.directory"); 83 if (cacheDir == null) { 84 cacheDir = prop.getProperty("cache.directory"); 85 } 86 if (cacheDir == null) { 87 cacheDir = LPS.getWorkDirectory() + File.separator + "cache"; 88 } 89 90 File cache = checkDirectory(cacheDir); 91 mLogger.info("application cache is at " + cacheDir); 92 93 if (mCompMgr == null) { 94 mCompMgr = new CompilationManager(null, cache, prop); 95 } 96 97 if (mScriptCache == null) { 98 String scacheDir = config.getInitParameter("lps.scache.directory"); 99 if (scacheDir == null) { 100 scacheDir = prop.getProperty("scache.directory"); 101 } 102 if (scacheDir == null) { 103 scacheDir = LPS.getWorkDirectory() + File.separator + "scache"; 104 } 105 File scache = checkDirectory(scacheDir); 106 mScriptCache = ScriptCompiler.initScriptCompilerCache(scache, prop); 107 } 108 109 String cmOption = prop.getProperty("compMgrDependencyOption"); 110 if (cmOption!=null) { 111 mLogger.debug("Setting cm option to \"" + cmOption + "\""); 112 mCompMgr.setProperty("recompile", cmOption); 113 } 114 } 115 } 116 117 118 122 protected final void respondImpl(HttpServletRequest req, HttpServletResponse res) 123 throws IOException 124 { 125 String fileName = LZHttpUtils.getRealPath(mContext, req); 126 127 String lzt = req.getParameter("lzt"); 128 String krank = req.getParameter("krank"); 129 boolean kranking = ("true".equals(krank) && "swf".equals(lzt)); 130 131 if (fileName.endsWith(".lzo") && kranking) { 132 fileName = fileName.substring(0, fileName.length()-1) + 'x'; 133 } 134 135 File file = new File(fileName); 138 if ( ! file.canRead() ) { 139 140 File base = new File(FileUtils.getBase(fileName)); 141 142 if (base.canRead() && base.isFile()) { 143 String tempFileName = doPreProcessing(req, fileName); 144 if (tempFileName != null) { 145 fileName = tempFileName; 146 } 147 } 148 } 149 150 if (! new File(fileName).exists()) { 151 boolean isOpt = fileName.endsWith(".lzo"); 152 boolean lzogz = new File(fileName+".gz").exists(); 153 if (!(isOpt && lzogz)) { 154 boolean hasFb = req.getParameter("fb") != null; 155 if (!(isOpt && hasFb)) { 156 res.sendError(HttpServletResponse.SC_NOT_FOUND, req.getRequestURI() + " not found"); 157 mLogger.info(req.getRequestURI() + " not found"); 158 return; 159 } else { 160 fileName = fileName.substring(0, fileName.length()-1) + 'x'; 161 } 162 } 163 } 164 165 try { 166 173 if (mCheckModifiedSince && !kranking) { 174 long lastModified = getLastModified(fileName, req); 175 lastModified = ((lastModified + 500L)/1000L) * 1000L; 177 if (notModified(lastModified, req, res)) { 178 return; 179 } 180 } 181 182 respondImpl(fileName, req, res); 183 184 String path = req.getServletPath(); 186 if (LPS.configuration.getApplicationOptions(path) == null) { 187 if (fileName.endsWith(".lzo")) { 189 fileName = fileName.substring(0, fileName.length()-1) + 'x'; 190 } 191 Canvas canvas = getCanvas(fileName, req); 192 LPS.configuration.setApplicationOptions(path, canvas.getSecurityOptions()); 193 } 194 195 } catch (CompilationError e) { 196 handleCompilationError(e, req, res); 197 } 198 } 199 200 protected void handleCompilationError(CompilationError e, 201 HttpServletRequest req, 202 HttpServletResponse res) 203 throws IOException 204 { 205 throw e; 206 } 207 208 214 private String doPreProcessing(HttpServletRequest req, String fileName) 215 throws IOException 216 { 217 StringBuffer s = HttpUtils.getRequestURL(req); 220 int len = s.length(); 221 if (len <= 4) { 223 return null; 224 } 225 s.delete(len-4, len); 226 227 229 HttpSession session = req.getSession(); 231 String sid = session.getId(); 232 String tempFileName = getTempFileName(fileName, sid); 233 File tempFile = new File(tempFileName); 234 235 tempFile.deleteOnExit(); 236 237 240 242 String surl = s.toString(); 243 244 URL url = new URL (surl); 245 mLogger.debug("Preprocessing request at " + surl); 246 GetMethod getRequest = new LZGetMethod(); 247 getRequest.setPath(url.getPath()); 248 getRequest.setQueryString(req.getQueryString()); 250 251 LZHttpUtils.proxyRequestHeaders(req, getRequest); 253 if (tempFile.exists()) { 255 long lastModified = tempFile.lastModified(); 256 getRequest.addRequestHeader("If-Modified-Since", 257 LZHttpUtils.getDateString(lastModified)); 258 } else { 259 LZBindingListener listener = (LZBindingListener)session.getAttribute("tmpl"); 265 if (listener == null) { 266 listener = new LZBindingListener(tempFileName); 267 session.setAttribute("tmpl", listener); 268 } else { 269 listener.addTempFile(tempFileName); 270 } 271 } 272 273 HttpClient htc = new HttpClient(); 274 htc.startSession(url); 275 276 int rc = htc.executeMethod(getRequest); 277 mLogger.debug("Response Status: " + rc); 278 if (rc >= 400) { 279 return null; 281 } if (rc != HttpServletResponse.SC_NOT_MODIFIED) { 282 FileOutputStream output = new FileOutputStream(tempFile); 283 try { 284 FileUtils.sendToStream(getRequest.getResponseBodyAsStream(), output); 286 } catch (FileUtils.StreamWritingException e) { 288 mLogger.warn("StreamWritingException while sending error: " + e.getMessage()); 289 } finally { 290 FileUtils.close(output); 291 } 292 } 293 294 return tempFileName; 295 } 296 297 301 private String getTempFileName(String fileName, String sid) 302 { 303 String webappPath = LZHttpUtils.getRealPath(mContext, "/"); 304 File source = mCompMgr.getCacheSourcePath(fileName, webappPath); 305 File cacheDir = source.getParentFile(); 306 if (cacheDir != null) { 307 cacheDir.mkdirs(); 308 } 309 String sourcePath = source.getAbsolutePath(); 310 StringBuffer buf = new StringBuffer (sourcePath); 311 int index = sourcePath.lastIndexOf(File.separator); 312 buf.insert(index + 1, "lzf-" + sid + "-"); 313 return buf.toString(); 314 } 315 316 320 private boolean notModified(long lastModified, HttpServletRequest req, 321 HttpServletResponse res) 322 throws IOException 323 { 324 if (lastModified != 0) { 325 326 String lms = LZHttpUtils.getDateString(lastModified); 327 328 mLogger.debug("Last-Modified: " + lms); 329 330 String ims = req.getHeader(LZHttpUtils.IF_MODIFIED_SINCE); 332 long ifModifiedSince = LZHttpUtils.getDate(ims); 333 334 if (ifModifiedSince != -1) { 335 336 mLogger.debug("If-Modified-Since: " + ims); 337 338 mLogger.debug("modsince " + ifModifiedSince 339 + " lastmod " + lastModified); 340 if (lastModified <= ifModifiedSince) { 341 res.setStatus(HttpServletResponse.SC_NOT_MODIFIED); 342 mLogger.info("Responding with NOT_MODIFIED"); 343 return true; 344 } 345 } 346 347 res.setHeader(LZHttpUtils.LAST_MODIFIED, lms); 348 } 349 350 return false; 351 } 352 353 359 protected long getLastModified(String fileName, HttpServletRequest req) 360 throws CompilationError, IOException 361 { 362 if (fileName.endsWith(".lzo") && "swf".equals(req.getParameter("lzt"))) { 368 File kranked = new File(fileName); 369 if (kranked.exists()) { 370 return kranked.lastModified(); 371 } else { 372 return 0; 373 } 374 } 375 376 if (fileName.endsWith(".lzo")) { 379 fileName = fileName.substring(0, fileName.length() - 1) + "x"; 380 } 381 382 Properties props = initCMgrProperties(req); 383 return mCompMgr.getLastModified(fileName, props); 384 } 385 386 407 static protected Properties initCMgrProperties(HttpServletRequest req) { 408 409 Properties props = new Properties (); 410 411 String swfversion = req.getParameter("lzr"); 413 if (swfversion == null) { 414 swfversion = LPS.getProperty("compiler.runtime.default", "swf6"); 415 } 416 props.setProperty(CompilationEnvironment.SWFVERSION_PROPERTY, swfversion); 417 418 props.setProperty(CompilationEnvironment.REMOTEDEBUG_PROPERTY, ""); 420 String remotedebug = req.getParameter(CompilationEnvironment.REMOTEDEBUG_PROPERTY); 421 if (remotedebug != null) { 422 props.setProperty(CompilationEnvironment.REMOTEDEBUG_PROPERTY, remotedebug); 423 } 424 425 if (mAllowRequestSOURCE) { 428 props.setProperty("logdebug", "false"); 430 String logdebug = req.getParameter("logdebug"); 431 if (logdebug != null) { 432 props.setProperty("logdebug", logdebug); 433 } 434 435 props.setProperty("debug", "false"); 437 String debug = req.getParameter("debug"); 438 if (debug != null) { 439 props.setProperty("debug", debug); 440 } 441 442 props.setProperty("sourcelocators", "false"); 444 String sl = req.getParameter("sourcelocators"); 445 if (sl != null) { 446 props.setProperty("sourcelocators", sl); 447 } 448 449 props.setProperty("profile", "false"); 451 String profile = req.getParameter("profile"); 452 if (profile != null) { 453 props.setProperty("profile", profile); 454 } 455 } 456 457 String proxied = req.getParameter("lzproxied"); 459 if (proxied != null) { 460 props.setProperty("lzproxied", proxied); 461 } 462 463 if (mAllowRecompile) { 464 String recompile = req.getParameter(CompilationManager.RECOMPILE); 465 if (recompile != null) { 466 String pwd = req.getParameter("pwd"); 468 if ( mAdminPassword == null || 469 (pwd != null && pwd.equals(mAdminPassword)) ) { 470 props.setProperty(CompilationManager.RECOMPILE, "true"); 471 } else { 472 mLogger.warn("lzrecompile attempted but not allowed"); 473 } 474 } 475 } 476 477 if (mAllowRequestKRANK) { 478 props.setProperty("krank", "false"); 484 String lzt = req.getParameter("lzt"); 485 String krank = req.getParameter("krank"); 486 if (krank != null && "swf".equals(lzt)) { 487 props.setProperty("krank", krank); 488 } 489 } 490 491 492 String encoding = ContentEncoding.chooseEncoding(req); 493 496 if ("swf5".equals(props.getProperty(CompilationEnvironment.SWFVERSION_PROPERTY)) 497 && (encoding != null)) { 498 props.setProperty(LZHttpUtils.CONTENT_ENCODING, encoding); 499 } 500 501 return props; 502 } 503 504 505 511 protected Canvas getCanvas(String fileName, HttpServletRequest req) 512 throws CompilationError, IOException 513 { 514 Properties props = initCMgrProperties(req); 515 return mCompMgr.getCanvas(fileName, props); 516 } 517 518 public static CompilationManager getCompilationManager() 519 { 520 return mCompMgr; 521 } 522 } 523 | Popular Tags |