/** * Copyright (c) 2014, the Railo Company Ltd. * Copyright (c) 2015, Lucee Assosication Switzerland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ package lucee.runtime.engine; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.instrument.Instrumentation; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.security.CodeSource; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.TimeZone; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.script.ScriptEngineFactory; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspException; import lucee.Info; import lucee.print; import lucee.cli.servlet.HTTPServletImpl; import lucee.commons.collection.MapFactory; import lucee.commons.io.CharsetUtil; import lucee.commons.io.DevNullOutputStream; import lucee.commons.io.FileUtil; import lucee.commons.io.IOUtil; import lucee.commons.io.SystemUtil; import lucee.commons.io.compress.CompressUtil; import lucee.commons.io.log.Log; import lucee.commons.io.res.Resource; import lucee.commons.io.res.ResourceProvider; import lucee.commons.io.res.ResourcesImpl; import lucee.commons.io.res.util.ResourceUtil; import lucee.commons.io.res.util.ResourceUtilImpl; import lucee.commons.io.retirement.RetireOutputStreamFactory; import lucee.commons.lang.ExceptionUtil; import lucee.commons.lang.Md5; import lucee.commons.lang.Pair; import lucee.commons.lang.StringUtil; import lucee.commons.lang.SystemOut; import lucee.commons.lang.types.RefBoolean; import lucee.commons.lang.types.RefBooleanImpl; import lucee.commons.net.HTTPUtil; import lucee.intergral.fusiondebug.server.FDControllerImpl; import lucee.loader.engine.CFMLEngine; import lucee.loader.engine.CFMLEngineFactory; import lucee.loader.engine.CFMLEngineFactorySupport; import lucee.loader.engine.CFMLEngineWrapper; import lucee.loader.osgi.BundleCollection; import lucee.loader.util.Util; import lucee.runtime.CFMLFactory; import lucee.runtime.CFMLFactoryImpl; import lucee.runtime.ComponentPageImpl; import lucee.runtime.PageContext; import lucee.runtime.PageContextImpl; import lucee.runtime.PageSource; import lucee.runtime.cache.CacheUtil; import lucee.runtime.config.Config; import lucee.runtime.config.ConfigImpl; import lucee.runtime.config.ConfigServer; import lucee.runtime.config.ConfigServerImpl; import lucee.runtime.config.ConfigWeb; import lucee.runtime.config.ConfigWebImpl; import lucee.runtime.config.DeployHandler; import lucee.runtime.config.Identification; import lucee.runtime.config.Password; import lucee.runtime.config.XMLConfigAdmin; import lucee.runtime.config.XMLConfigFactory; import lucee.runtime.config.XMLConfigFactory.UpdateInfo; import lucee.runtime.config.XMLConfigServerFactory; import lucee.runtime.config.XMLConfigWebFactory; import lucee.runtime.engine.listener.CFMLServletContextListener; import lucee.runtime.exp.ApplicationException; import lucee.runtime.exp.PageException; import lucee.runtime.exp.PageRuntimeException; import lucee.runtime.exp.PageServletException; import lucee.runtime.extension.ExtensionDefintion; import lucee.runtime.extension.RHExtension; import lucee.runtime.functions.other.CreateUniqueId; import lucee.runtime.instrumentation.InstrumentationFactory; import lucee.runtime.jsr223.ScriptEngineFactoryImpl; import lucee.runtime.net.http.HTTPServletRequestWrap; import lucee.runtime.net.http.HttpServletRequestDummy; import lucee.runtime.net.http.HttpServletResponseDummy; import lucee.runtime.net.http.ReqRspUtil; import lucee.runtime.op.CastImpl; import lucee.runtime.op.Caster; import lucee.runtime.op.CreationImpl; import lucee.runtime.op.DecisionImpl; import lucee.runtime.op.ExceptonImpl; import lucee.runtime.op.IOImpl; import lucee.runtime.op.JavaProxyUtilImpl; import lucee.runtime.op.OperationImpl; import lucee.runtime.op.StringsImpl; import lucee.runtime.osgi.OSGiUtil; import lucee.runtime.thread.ThreadUtil; import lucee.runtime.type.Struct; import lucee.runtime.type.StructImpl; import lucee.runtime.util.Cast; import lucee.runtime.util.ClassUtil; import lucee.runtime.util.ClassUtilImpl; import lucee.runtime.util.Creation; import lucee.runtime.util.DBUtil; import lucee.runtime.util.DBUtilImpl; import lucee.runtime.util.Decision; import lucee.runtime.util.Excepton; import lucee.runtime.util.HTMLUtil; import lucee.runtime.util.HTMLUtilImpl; import lucee.runtime.util.HTTPUtilImpl; import lucee.runtime.util.IO; import lucee.runtime.util.ListUtil; import lucee.runtime.util.ListUtilImpl; import lucee.runtime.util.ORMUtil; import lucee.runtime.util.ORMUtilImpl; import lucee.runtime.util.Operation; import lucee.runtime.util.PageContextUtil; import lucee.runtime.util.Strings; import lucee.runtime.util.SystemUtilImpl; import lucee.runtime.util.TemplateUtil; import lucee.runtime.util.TemplateUtilImpl; import lucee.runtime.util.ZipUtil; import lucee.runtime.util.ZipUtilImpl; import lucee.runtime.video.VideoUtil; import lucee.runtime.video.VideoUtilImpl; import org.apache.commons.net.telnet.TerminalTypeOptionHandler; import org.apache.felix.framework.Felix; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.Version; //import com.intergral.fusiondebug.server.FDControllerFactory; /** * The CFMl Engine */ public final class CFMLEngineImpl implements CFMLEngine { private static Map<String,CFMLFactory> initContextes=MapFactory.<String,CFMLFactory>getConcurrentMap(); private static Map<String,CFMLFactory> contextes=MapFactory.<String,CFMLFactory>getConcurrentMap(); private ConfigServerImpl configServer=null; private static CFMLEngineImpl engine=null; private CFMLEngineFactory factory; private final ControllerStateImpl controlerState=new ControllerStateImpl(true); private boolean allowRequestTimeout=true; private Monitor monitor; private List<ServletConfig> servletConfigs=new ArrayList<ServletConfig>(); private long uptime; private InfoImpl info; private BundleCollection bundleCollection; private ScriptEngineFactory cfmlScriptEngine; private ScriptEngineFactory cfmlTagEngine; private ScriptEngineFactory luceeScriptEngine; private ScriptEngineFactory luceeTagEngine; private Controler controler; private CFMLServletContextListener scl; //private static CFMLEngineImpl engine=new CFMLEngineImpl(); private CFMLEngineImpl(CFMLEngineFactory factory, BundleCollection bc) { this.factory=factory; this.bundleCollection=bc; // log the startup process String logDir=SystemUtil.getSystemPropOrEnvVar("startlogdirectory", null);//"/Users/mic/Tmp/"); if(logDir!=null) { File f = new File(logDir); if(f.isDirectory()) { String logName=SystemUtil.getSystemPropOrEnvVar("logName", "stacktrace"); int timeRange=Caster.toIntValue(SystemUtil.getSystemPropOrEnvVar("timeRange", "stacktrace"),1); LogST._do(f, logName, timeRange); } } // happen when Lucee is loaded directly if(bundleCollection==null) { try{ Properties prop = InfoImpl.getDefaultProperties(null); // read the config from default.properties Map<String,Object> config=new HashMap<String, Object>(); Iterator<Entry<Object, Object>> it = prop.entrySet().iterator(); Entry<Object, Object> e; String k; while(it.hasNext()){ e = it.next(); k=(String) e.getKey(); if(!k.startsWith("org.") && !k.startsWith("felix.")) continue; config.put(k, CFMLEngineFactorySupport.removeQuotes((String)e.getValue(),true)); } config.put( Constants.FRAMEWORK_BOOTDELEGATION, "lucee.*"); Felix felix = factory.getFelix(factory.getResourceRoot(),config); bundleCollection=new BundleCollection(felix, felix, null); //bundleContext=bundleCollection.getBundleContext(); } catch(Throwable t) { ExceptionUtil.rethrowIfNecessary(t); if(t instanceof Error) throw (Error)t; throw new RuntimeException(t); } } this.info=new InfoImpl(bundleCollection==null?null:bundleCollection.core); Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); // MUST better location for this UpdateInfo updateInfo; Resource configDir=null; try { configDir = getSeverContextConfigDirectory(factory); updateInfo=XMLConfigFactory.doNew(this,configDir, true); } catch (IOException e) { throw new PageRuntimeException(e); } CFMLEngineFactory.registerInstance((this));// patch, not really good but it works ConfigServerImpl cs = getConfigServerImpl(); controler = new Controler(cs,initContextes,5*1000,controlerState); controler.setDaemon(true); controler.setPriority(Thread.MIN_PRIORITY); boolean disabled=Caster.toBooleanValue(SystemUtil.getSystemPropOrEnvVar(SystemUtil.SETTING_CONTROLLER_DISABLED,null),false); if (!disabled) { // start the controller SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), "Start CFML Controller"); controler.start(); } boolean isRe=configDir==null?false:XMLConfigFactory.isRequiredExtension(this, configDir); boolean installExtensions=Caster.toBooleanValue(SystemUtil.getSystemPropOrEnvVar("lucee.extensions.install",null),true); // copy bundled extension to local extension directory (if never done before) if(installExtensions && updateInfo.updateType!=XMLConfigFactory.NEW_NONE) { deployBundledExtension(cs); SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), "copy bundled extension to local extension directory (if never done before)"); } // required extensions // if we have a "fresh" install Set<ExtensionDefintion> extensions; if(installExtensions && (updateInfo.updateType==XMLConfigFactory.NEW_FRESH || updateInfo.updateType==XMLConfigFactory.NEW_FROM4)) { List<ExtensionDefintion> ext = info.getRequiredExtension(); extensions = toSet(null,ext); SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), "detected Extensions to install (new;"+updateInfo.updateType+"):"+toList(extensions)); } // if we have an update we update the extension that re installed and we have an older version as defined in the manifest else if(installExtensions && (updateInfo.updateType==XMLConfigFactory.NEW_MINOR || !isRe)) { extensions = new HashSet<ExtensionDefintion>(); Iterator<ExtensionDefintion> it = info.getRequiredExtension().iterator(); ExtensionDefintion ed; RHExtension rhe; Version edVersion,rheVersion; while(it.hasNext()){ ed = it.next(); edVersion = OSGiUtil.toVersion(ed.getVersion(), null); if(ed.getVersion()==null) { continue; // no version definition no update } try{ rhe = XMLConfigAdmin.hasRHExtensions(cs, new ExtensionDefintion(ed.getId())); if(rhe==null) { rheVersion=null; Version since=ed.getSince(); if(since==null || updateInfo.oldVersion==null || !Util.isNewerThan(since, updateInfo.oldVersion)) continue; // not installed we do not update extensions.add(ed); } else rheVersion=OSGiUtil.toVersion(rhe.getVersion(), null); // if the installed is older than the one defined in the manifest we update (if possible) //print.e("----- "+ed.getId()+" ------"); //print.e(ed.getVersion()+"->"+edVersion); //if(rhe!=null)print.e(rhe.getVersion()+"->"+rheVersion); //print.e(rheVersion!=null && OSGiUtil.isNewerThan(edVersion,rheVersion)); if(rheVersion!=null && OSGiUtil.isNewerThan(edVersion,rheVersion)) { // TODO do none OSGi version number comparsion extensions.add(ed); } } catch(Throwable t){ ExceptionUtil.rethrowIfNecessary(t); // fails we update extensions.add(ed); } } SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), "detected Extensions to install (minor;"+updateInfo.updateType+"):"+toList(extensions)); } else { extensions = new HashSet<ExtensionDefintion>(); SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), "no update"); } // XMLConfigAdmin.hasRHExtensions(ci, ed) // install extension defined String extensionIds=SystemUtil.getSystemPropOrEnvVar("lucee-extensions",null); // old no longer used if(StringUtil.isEmpty(extensionIds,true)) extensionIds=SystemUtil.getSystemPropOrEnvVar("lucee.extensions",null); if(!StringUtil.isEmpty(extensionIds,true)) { SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), "extensions to install defined in env variable or system property:"+extensionIds); List<ExtensionDefintion> _extensions = RHExtension.toExtensionDefinitions(extensionIds); extensions=toSet(extensions,_extensions); } if(extensions.size()>0) { boolean sucess=DeployHandler.deployExtensions( cs, extensions.toArray(new ExtensionDefintion[extensions.size()]), cs.getLog("deploy", true) ); if(sucess && configDir!=null)XMLConfigFactory.updateRequiredExtension(this, configDir); SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), "installed extensions:"+toList(extensions)); } else if(configDir!=null)XMLConfigFactory.updateRequiredExtension(this, configDir); touchMonitor(cs); SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), "touched monitors"); this.uptime=System.currentTimeMillis(); //this.config=config; } public static Set<ExtensionDefintion> toSet(Set<ExtensionDefintion> set, List<ExtensionDefintion> list) { LinkedHashMap<String, ExtensionDefintion> map=new LinkedHashMap<String, ExtensionDefintion>(); ExtensionDefintion ed; // set > map if(set!=null) { Iterator<ExtensionDefintion> it = set.iterator(); while(it.hasNext()){ ed = it.next(); map.put(ed.toString(),ed); } } // list > map if(list!=null) { Iterator<ExtensionDefintion> it = list.iterator(); while(it.hasNext()){ ed = it.next(); map.put(ed.toString(),ed); } } // to Set LinkedHashSet<ExtensionDefintion> rtn = new LinkedHashSet<ExtensionDefintion>(); Iterator<ExtensionDefintion> it = map.values().iterator(); while(it.hasNext()){ ed = it.next(); rtn.add(ed); } return rtn; } public static String toList(Set<ExtensionDefintion> set) { StringBuilder sb=new StringBuilder(); Iterator<ExtensionDefintion> it = set.iterator(); ExtensionDefintion ed; while(it.hasNext()){ ed = it.next(); if(sb.length()>0) sb.append(", "); sb.append(ed.toString()); } return sb.toString(); } private void deployBundledExtension(ConfigServerImpl cs) { Resource dir = cs.getLocalExtensionProviderDirectory(); List<ExtensionDefintion> existing = DeployHandler.getLocalExtensions(cs); Map<String,ExtensionDefintion> existingMap=new HashMap<String, ExtensionDefintion>(); { Iterator<ExtensionDefintion> it = existing.iterator(); ExtensionDefintion ed; while(it.hasNext()) { ed=it.next(); try { existingMap.put(ed.getSource().getName(), ed); } catch (ApplicationException e) {} } } Log log = cs.getLog("deploy"); // get the index ClassLoader cl=CFMLEngineFactory.getInstance().getCFMLEngineFactory().getClass().getClassLoader(); InputStream is = cl.getResourceAsStream("extensions/.index"); if(is==null)is = cl.getResourceAsStream("/extensions/.index"); if(is==null)is = SystemUtil.getResourceAsStream(null, "/extensions/.index"); if(is==null) { log.error("extract-extension", "could not found [/extensions/.index] defined in the index in the lucee.jar"); return; } try { String index=IOUtil.toString(is, CharsetUtil.UTF8); log.info("extract-extension", "the following extensions are bundled with the lucee.jar ["+index+"]"); String[] names = lucee.runtime.type.util.ListUtil.listToStringArray(index, ';'); String name; Resource temp=null; RHExtension rhe; ExtensionDefintion exist; Iterator<ExtensionDefintion> it; for(int i=0;i<names.length;i++){ name=names[i]; if(StringUtil.isEmpty(name,true)) continue; name=name.trim(); // does it already exist? if(existingMap.containsKey(name)) { continue; } is = cl.getResourceAsStream("extensions/"+name); if(is==null)is = cl.getResourceAsStream("/extensions/"+name); if(is==null) { log.error("extract-extension", "could not found extension ["+name+"] defined in the index in the lucee.jar"); continue; } try { temp=SystemUtil.getTempDirectory().getRealResource(name); ResourceUtil.touch(temp); Util.copy(is, temp.getOutputStream(),false,true); rhe = new RHExtension(cs, temp, false); ExtensionDefintion alreadyExists=null; it = existing.iterator(); while(it.hasNext()){ exist = it.next(); if(exist.equals(rhe)) { alreadyExists=exist; break; } } String trgName=rhe.getId()+"-"+rhe.getVersion()+".lex"; if(alreadyExists==null) { temp.moveTo(dir.getRealResource(trgName)); log.info("extract-extension", "added ["+name+"] to ["+dir+"]"); } else if(!alreadyExists.getSource().getName().equals(trgName)) { log.info("extract-extension", "rename ["+alreadyExists.getSource()+"] to ["+trgName+"]"); alreadyExists.getSource().moveTo( alreadyExists.getSource().getParentResource().getRealResource(trgName) ); } // now we check all extension name (for extension no longer delivered by lucee) it = existing.iterator(); while(it.hasNext()){ exist = it.next(); trgName=exist.getId()+"-"+exist.getVersion()+".lex"; if(!trgName.equals(exist.getSource().getName())) { exist.getSource().moveTo( exist.getSource().getParentResource().getRealResource(trgName) ); log.info("extract-extension", "rename ["+exist.getSource()+"] to ["+trgName+"]"); } } } finally { if(temp!=null && temp.exists())temp.delete(); } } } catch(Throwable t){ ExceptionUtil.rethrowIfNecessary(t); log.error("extract-extension", t); } return; } private void deployBundledExtensionZip(ConfigServerImpl cs) { Resource dir = cs.getLocalExtensionProviderDirectory(); List<ExtensionDefintion> existing = DeployHandler.getLocalExtensions(cs); String sub="extensions/"; // MUST this does not work on windows! we need to add an index ZipEntry entry; ZipInputStream zis = null; try { CodeSource src = CFMLEngineFactory.class.getProtectionDomain().getCodeSource(); if (src == null) return; URL loc = src.getLocation(); zis=new ZipInputStream(loc.openStream()); String path,name; int index; Resource temp; RHExtension rhe; Iterator<ExtensionDefintion> it; ExtensionDefintion exist; while ((entry = zis.getNextEntry())!= null) { path = entry.getName(); if(path.startsWith(sub) && path.endsWith(".lex")) { // ignore non lex files or file from else where index=path.lastIndexOf('/')+1; if(index==sub.length()) { // ignore sub directories name=path.substring(index); temp=null; try { temp = SystemUtil.getTempDirectory().getRealResource(name); ResourceUtil.touch(temp); Util.copy(zis, temp.getOutputStream(),false,true); rhe = new RHExtension(cs, temp, false); boolean alreadyExists=false; it = existing.iterator(); while(it.hasNext()){ exist = it.next(); if(exist.equals(rhe)) { alreadyExists=true; break; } } if(!alreadyExists) { temp.moveTo(dir.getRealResource(name)); } } finally { if(temp!=null && temp.exists())temp.delete(); } } } zis.closeEntry(); } } catch(Throwable t){ ExceptionUtil.rethrowIfNecessary(t);// TODO log this } finally { Util.closeEL(zis); } return; } public void touchMonitor(ConfigServerImpl cs) { if(monitor!=null && monitor.isAlive()) return; monitor = new Monitor(cs,controlerState); monitor.setDaemon(true); monitor.setPriority(Thread.MIN_PRIORITY); monitor.start(); } /** * get singelton instance of the CFML Engine * @param factory * @return CFMLEngine */ public static synchronized CFMLEngine getInstance(CFMLEngineFactory factory,BundleCollection bc) { if(engine==null) { if(SystemUtil.getLoaderVersion()<6.0D) { // windows needs 6.0 because restart is not working with older versions if(SystemUtil.isWindows()) throw new RuntimeException("You need to update a newer lucee.jar to run this version, you can download the latest jar from http://download.lucee.org."); else if(SystemUtil.getLoaderVersion()<5.8D) throw new RuntimeException("You need to update your lucee.jar to run this version, you can download the latest jar from http://download.lucee.org."); else if(SystemUtil.getLoaderVersion()<5.9D) SystemOut.printDate("To use all features Lucee provides, you need to update your lucee.jar, you can download the latest jar from http://download.lucee.org."); } engine=new CFMLEngineImpl(factory,bc); } return engine; } /** * get singelton instance of the CFML Engine, throwsexception when not already init * @param factory * @return CFMLEngine */ public static synchronized CFMLEngine getInstance() throws ServletException { if(engine!=null) return engine; throw new ServletException("CFML Engine is not loaded"); } @Override public void addServletConfig(ServletConfig config) throws ServletException { // FUTURE remove if("LuceeServletContextListener".equals(config.getServletName())) { try { //Method m = config.getClass().getMethod("getServletContextEvent", new Class[0]); //ServletContextEvent sce=(ServletContextEvent) m.invoke(config, new Object[0]); String status=config.getInitParameter("status"); if("release".equalsIgnoreCase(status)) reset(); } catch (Exception e) { e.printStackTrace(); } return; } // add EventListener if(scl==null) { addEventListener(config.getServletContext()); } servletConfigs.add(config); String real=ReqRspUtil.getRootPath(config.getServletContext()); if(!initContextes.containsKey(real)) { CFMLFactory jspFactory = loadJSPFactory(getConfigServerImpl(),config,initContextes.size()); initContextes.put(real,jspFactory); } } private void addEventListener(ServletContext sc) { // TOMCAT if("org.apache.catalina.core.ApplicationContextFacade".equals(sc.getClass().getName())) { Object obj=extractServletContext(sc); obj=extractServletContext(obj); if("org.apache.catalina.core.StandardContext".equals(obj.getClass().getName())) { Method m=null; try { // TODO check if we already have a listener (lucee.loader.servlet.LuceeServletContextListener), if so we do nothing //sc.getApplicationLifecycleListeners(); m=obj.getClass().getMethod("addApplicationLifecycleListener", new Class[]{Object.class}); CFMLServletContextListener tmp; m.invoke(obj, new Object[]{tmp=new CFMLServletContextListener(this)}); scl=tmp; return; } catch (Exception e) {} } } // GENERAL try add Event method directly (does not work with tomcat) try{ CFMLServletContextListener tmp = new CFMLServletContextListener(this); sc.addListener(tmp); scl=tmp; return; } catch(Exception e) {} SystemOut.printDate("Lucee was not able to register an event listener with "+(sc==null?"null":sc.getClass().getName())); } private Object extractServletContext(Object sc) { Class<?> clazz = sc.getClass(); Field f=null; try { f = clazz.getDeclaredField("context"); }catch (Exception e) {} if(f!=null) { f.setAccessible(true); Object obj=null; try { obj = f.get(sc); } catch (Exception e) {} return obj; } return null; } @Override public ConfigServer getConfigServer(Password password) throws PageException { getConfigServerImpl().checkAccess(password); return configServer; } @Override public ConfigServer getConfigServer(String key, long timeNonce) throws PageException { getConfigServerImpl().checkAccess(key,timeNonce); return configServer; } public void setConfigServerImpl(ConfigServerImpl cs) { this.configServer=cs; } private ConfigServerImpl getConfigServerImpl() { if(configServer==null) { try { Resource context = getSeverContextConfigDirectory(factory); //CFMLEngineFactory.registerInstance(this);// patch, not really good but it works configServer=XMLConfigServerFactory.newInstance( this, initContextes, contextes, context); } catch (Exception e) { e.printStackTrace(); } } return configServer; } private Resource getSeverContextConfigDirectory(CFMLEngineFactory factory) throws IOException { ResourceProvider frp = ResourcesImpl.getFileResourceProvider(); return frp.getResource(factory.getResourceRoot().getAbsolutePath()).getRealResource("context"); } private CFMLFactoryImpl loadJSPFactory(ConfigServerImpl configServer, ServletConfig sg, int countExistingContextes) throws ServletException { try { if(XMLConfigWebFactory.LOG) SystemOut.printDate("load Context"); // Load Config RefBoolean isCustomSetting=new RefBooleanImpl(); Resource configDir=getConfigDirectory(sg,configServer,countExistingContextes,isCustomSetting); if(XMLConfigWebFactory.LOG) SystemOut.printDate("got context directory"); CFMLFactoryImpl factory=new CFMLFactoryImpl(this,sg); if(XMLConfigWebFactory.LOG) SystemOut.printDate("init factory"); ConfigWebImpl config=XMLConfigWebFactory.newInstance(this,factory,configServer,configDir,isCustomSetting.toBooleanValue(),sg); if(XMLConfigWebFactory.LOG) SystemOut.printDate("loaded config"); factory.setConfig(config); return factory; } catch (Exception e) { ServletException se= new ServletException(e.getMessage()); se.setStackTrace(e.getStackTrace()); throw se; } } /** * loads Configuration File from System, from init Parameter from web.xml * @param sg * @param configServer * @param countExistingContextes * @return return path to directory */ private Resource getConfigDirectory(ServletConfig sg, ConfigServerImpl configServer, int countExistingContextes, RefBoolean isCustomSetting) throws PageServletException { isCustomSetting.setValue(true); ServletContext sc=sg.getServletContext(); String strConfig=sg.getInitParameter("configuration"); if(StringUtil.isEmpty(strConfig))strConfig=sg.getInitParameter("lucee-web-directory"); if(StringUtil.isEmpty(strConfig))strConfig=System.getProperty("lucee.web.dir"); if(StringUtil.isEmpty(strConfig)) { isCustomSetting.setValue(false); strConfig="{web-root-directory}/WEB-INF/lucee/"; } // only for backward compatibility else if(strConfig.startsWith("/WEB-INF/lucee/"))strConfig="{web-root-directory}"+strConfig; strConfig=StringUtil.removeQuotes(strConfig,true); // static path is not allowed if(countExistingContextes>1 && strConfig!=null && strConfig.indexOf('{')==-1){ String text="static path ["+strConfig+"] for servlet init param [lucee-web-directory] is not allowed, path must use a web-context specific placeholder."; System.err.println(text); throw new PageServletException(new ApplicationException(text)); } strConfig=SystemUtil.parsePlaceHolder(strConfig,sc,configServer.getLabels()); ResourceProvider frp = ResourcesImpl.getFileResourceProvider(); Resource root = frp.getResource(ReqRspUtil.getRootPath(sc)); Resource res; Resource configDir=ResourceUtil.createResource(res=root.getRealResource(strConfig), FileUtil.LEVEL_PARENT_FILE,FileUtil.TYPE_DIR); if(configDir==null) { configDir=ResourceUtil.createResource(res=frp.getResource(strConfig), FileUtil.LEVEL_GRAND_PARENT_FILE,FileUtil.TYPE_DIR); } if(configDir==null && !isCustomSetting.toBooleanValue()) { try { res.createDirectory(true); configDir=res; } catch (IOException e) { throw new PageServletException(Caster.toPageException(e)); } } if(configDir==null) { throw new PageServletException(new ApplicationException("path ["+strConfig+"] is invalid")); } if(!configDir.exists() || ResourceUtil.isEmptyDirectory(configDir, null)){ Resource railoRoot; // there is a railo directory if(configDir.getName().equals("lucee") && (railoRoot=configDir.getParentResource().getRealResource("railo")).isDirectory()) { try { copyRecursiveAndRename(railoRoot,configDir); } catch (IOException e) { try { configDir.createDirectory(true); } catch (IOException ioe) {} return configDir; } // zip the railo-server di and delete it (optional) try { Resource p=railoRoot.getParentResource(); CompressUtil.compress(CompressUtil.FORMAT_ZIP, railoRoot, p.getRealResource("railo-web-context-old.zip"), false, -1); ResourceUtil.removeEL(railoRoot, true); } catch(Throwable t){ExceptionUtil.rethrowIfNecessary(t);} } else { try { configDir.createDirectory(true); } catch (IOException e) {} } } return configDir; } private File getDirectoryByProp(String name) { String value=System.getProperty(name); if(Util.isEmpty(value,true)) return null; File dir=new File(value); dir.mkdirs(); if (dir.isDirectory()) return dir; return null; } private static void copyRecursiveAndRename(Resource src,Resource trg) throws IOException { if(!src.exists()) return ; if(src.isDirectory()) { if(!trg.exists())trg.mkdirs(); Resource[] files = src.listResources(); for(int i=0;i<files.length;i++) { copyRecursiveAndRename(files[i],trg.getRealResource(files[i].getName())); } } else if(src.isFile()) { if(trg.getName().endsWith(".rc") || trg.getName().startsWith(".")) { return; } if(trg.getName().equals("railo-web.xml.cfm")) { trg=trg.getParentResource().getRealResource("lucee-web.xml.cfm"); // cfLuceeConfiguration InputStream is = src.getInputStream(); OutputStream os = trg.getOutputStream(); try{ String str=Util.toString(is); str=str.replace("<cfRailoConfiguration", "<!-- copy from Railo context --><cfLuceeConfiguration"); str=str.replace("</cfRailoConfiguration", "</cfLuceeConfiguration"); str=str.replace("<railo-configuration", "<lucee-configuration"); str=str.replace("</railo-configuration", "</lucee-configuration"); str=str.replace("{railo-config}", "{lucee-config}"); str=str.replace("{railo-server}", "{lucee-server}"); str=str.replace("{railo-web}", "{lucee-web}"); str=str.replace("\"railo.commons.", "\"lucee.commons."); str=str.replace("\"railo.runtime.", "\"lucee.runtime."); str=str.replace("\"railo.cfx.", "\"lucee.cfx."); str=str.replace("/railo-context.ra", "/lucee-context.lar"); str=str.replace("/railo-context", "/lucee"); str=str.replace("railo-server-context", "lucee-server"); str=str.replace("http://www.getrailo.org", "http://release.lucee.org"); str=str.replace("http://www.getrailo.com", "http://release.lucee.org"); ByteArrayInputStream bais = new ByteArrayInputStream(str.getBytes()); try { Util.copy(bais, os); bais.close(); } finally { Util.closeEL(is, os); } } finally { Util.closeEL(is,os); } return; } InputStream is = src.getInputStream(); OutputStream os = trg.getOutputStream(); try{ Util.copy(is, os); } finally { Util.closeEL(is, os); } } } @Override public CFMLFactory getCFMLFactory(ServletConfig srvConfig,HttpServletRequest req) throws ServletException { ServletContext srvContext = srvConfig.getServletContext(); String real=ReqRspUtil.getRootPath(srvContext); ConfigServerImpl cs = getConfigServerImpl(); // Load JspFactory CFMLFactory factory=contextes.get(real); if(factory==null) { factory=initContextes.get(real); if(factory==null) { factory=loadJSPFactory(cs,srvConfig,initContextes.size()); initContextes.put(real,factory); } contextes.put(real,factory); try { String cp = req.getContextPath(); if(cp==null)cp=""; ((CFMLFactoryImpl)factory).setURL(new URL(req.getScheme(),req.getServerName(),req.getServerPort(),cp)); } catch (MalformedURLException e) { e.printStackTrace(); } } return factory; } @Override public void service(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException { _service(servlet, req, rsp, Request.TYPE_LUCEE); } @Override public void serviceCFML(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException { _service(servlet, req, rsp, Request.TYPE_CFML); } @Override public void serviceRest(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException { _service(servlet, new HTTPServletRequestWrap(req), rsp, Request.TYPE_REST); } private void _service(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp, short type) throws ServletException, IOException { CFMLFactoryImpl factory=(CFMLFactoryImpl) getCFMLFactory(servlet.getServletConfig(), req); // is Lucee dialect enabled? if(type==Request.TYPE_LUCEE) { if(!((ConfigImpl)factory.getConfig()).allowLuceeDialect()){ try { PageContextImpl.notSupported(); } catch (ApplicationException e) { throw new PageServletException(e); } } } PageContextImpl pc = factory.getPageContextImpl(servlet,req,rsp,null,false,-1,false,false,false,-1,true,false); try { Request r=new Request(pc,type); r.start(); long ended=-1; do { SystemUtil.wait(Thread.currentThread(),1000); // done? if(r.isDone()) { //print.e("mas-done:"+System.currentTimeMillis()); break; } // reach request timeout else if(ended==-1 && (pc.getStartTime()+pc.getRequestTimeout())<System.currentTimeMillis()) { //print.e("req-time:"+System.currentTimeMillis()); CFMLFactoryImpl.terminate(pc,false); ended=System.currentTimeMillis(); // break; we do not break here, we give the thread itself the chance to end we need the exception output } // the thread itself seem blocked, so we release this thread else if(ended>-1 && ended+10000<=System.currentTimeMillis()) { //print.e("give-up:"+System.currentTimeMillis()); break; } } while(true); //print.e("done: "+System.currentTimeMillis()); } finally { factory.releaseLuceePageContext(pc,false); } } @Override public void serviceFile(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException { req=new HTTPServletRequestWrap(req); CFMLFactory factory=getCFMLFactory( servlet.getServletConfig(), req); ConfigWeb config = factory.getConfig(); PageSource ps = config.getPageSourceExisting(null, null, req.getServletPath(), false, true, true, false); //Resource res = ((ConfigWebImpl)config).getPhysicalResourceExistingX(null, null, req.getServletPath(), false, true, true); if(ps==null) { rsp.sendError(404); } else { Resource res = ps.getResource(); if(res==null) { rsp.sendError(404); } else { ReqRspUtil.setContentLength(rsp,res.length()); String mt = servlet.getServletContext().getMimeType(req.getServletPath()); if(!StringUtil.isEmpty(mt))ReqRspUtil.setContentType(rsp,mt); IOUtil.copy(res, rsp.getOutputStream(), true); } } } /*private String getContextList() { return List.arrayToList((String[])contextes.keySet().toArray(new String[contextes.size()]),", "); }*/ @Override public String getVersion() { return info.getVersion().toString(); } @Override public Info getInfo() { return info; } @Override public String getUpdateType() { return getConfigServerImpl().getUpdateType(); } @Override public URL getUpdateLocation() { return getConfigServerImpl().getUpdateLocation(); } @Override public Identification getIdentification() { return getConfigServerImpl().getIdentification(); } @Override public boolean can(int type, Password password) { return getConfigServerImpl().passwordEqual(password); } @Override public CFMLEngineFactory getCFMLEngineFactory() { return factory; } @Override public void serviceAMF(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException { throw new ServletException("AMFServlet is no longer supported, use BrokerServlet instead."); //req=new HTTPServletRequestWrap(req); //getCFMLFactory(servlet.getServletConfig(), req).getConfig().getAMFEngine().service(servlet,new HTTPServletRequestWrap(req),rsp); } @Override public void reset() { reset(null); } @Override public void reset(String configId) { SystemOut.printDate("reset CFML Engine"); getControler().close(); RetireOutputStreamFactory.close(); releaseCache(getConfigServerImpl()); CFMLFactoryImpl cfmlFactory; //ScopeContext scopeContext; try { Iterator<String> it = contextes.keySet().iterator(); while(it.hasNext()) { try { cfmlFactory=(CFMLFactoryImpl) contextes.get(it.next()); if(configId!=null && !configId.equals(cfmlFactory.getConfigWebImpl().getIdentification().getId())) continue; // scopes try{cfmlFactory.getScopeContext().clear();}catch(Throwable t){ExceptionUtil.rethrowIfNecessary(t);} // PageContext try{cfmlFactory.resetPageContext();}catch(Throwable t){ExceptionUtil.rethrowIfNecessary(t);} // Query Cache try{ PageContext pc = ThreadLocalPageContext.get(); if(pc!=null) { pc.getConfig().getCacheHandlerCollection(Config.CACHE_TYPE_QUERY,null).clear(pc); pc.getConfig().getCacheHandlerCollection(Config.CACHE_TYPE_FUNCTION,null).clear(pc); pc.getConfig().getCacheHandlerCollection(Config.CACHE_TYPE_INCLUDE,null).clear(pc); } //cfmlFactory.getDefaultQueryCache().clear(null); }catch(Throwable t){ExceptionUtil.rethrowIfNecessary(t);} // Gateway try{ cfmlFactory.getConfigWebImpl().getGatewayEngine().reset();}catch(Throwable t){ExceptionUtil.rethrowIfNecessary(t);} // Cache releaseCache(cfmlFactory.getConfigWebImpl()); } catch(Throwable t){ExceptionUtil.rethrowIfNecessary(t);} } } finally { // Controller controlerState.setActive(false); } } public static void releaseCache(Config config) { CacheUtil.releaseAll(config); if(config instanceof ConfigServer)CacheUtil.releaseAllApplication(); } @Override public Cast getCastUtil() { return CastImpl.getInstance(); } @Override public Operation getOperatonUtil() { return OperationImpl.getInstance(); } @Override public Decision getDecisionUtil() { return DecisionImpl.getInstance(); } @Override public Excepton getExceptionUtil() { return ExceptonImpl.getInstance(); } @Override public Object getJavaProxyUtil() { // FUTURE return JavaProxyUtil return new JavaProxyUtilImpl(); } @Override public Creation getCreationUtil() { return CreationImpl.getInstance(this); } @Override public IO getIOUtil() { return IOImpl.getInstance(); } @Override public Strings getStringUtil() { return StringsImpl.getInstance(); } @Override public Object getFDController() { engine.allowRequestTimeout(false); return new FDControllerImpl(engine,engine.getConfigServerImpl().getSerialNumber()); } public Map<String,CFMLFactory> getCFMLFactories() { return initContextes; } @Override public lucee.runtime.util.ResourceUtil getResourceUtil() { return ResourceUtilImpl.getInstance(); } @Override public lucee.runtime.util.HTTPUtil getHTTPUtil() { return HTTPUtilImpl.getInstance(); } @Override public PageContext getThreadPageContext() { return ThreadLocalPageContext.get(); } @Override public Config getThreadConfig() { return ThreadLocalPageContext.getConfig(); } @Override public void registerThreadPageContext(PageContext pc) { ThreadLocalPageContext.register(pc); } @Override public VideoUtil getVideoUtil() { return VideoUtilImpl.getInstance(); } @Override public ZipUtil getZipUtil() { return ZipUtilImpl.getInstance(); } /*public String getState() { return info.getStateAsString(); }*/ public void allowRequestTimeout(boolean allowRequestTimeout) { this.allowRequestTimeout=allowRequestTimeout; } public boolean allowRequestTimeout() { return allowRequestTimeout; } public boolean isRunning() { try{ CFMLEngine other = CFMLEngineFactory.getInstance(); // FUTURE patch, do better impl when changing loader if(other!=this && controlerState.active() && !(other instanceof CFMLEngineWrapper)) { SystemOut.printDate("CFMLEngine is still set to true but no longer valid, "+lucee.runtime.config.Constants.NAME+" disable this CFMLEngine."); controlerState.setActive(false); reset(); return false; } } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} return controlerState.active(); } public boolean active() { return controlerState.active(); } public ControllerState getControllerState() { return controlerState; } @Override public void cli(Map<String, String> config, ServletConfig servletConfig) throws IOException,JspException,ServletException { ServletContext servletContext = servletConfig.getServletContext(); HTTPServletImpl servlet=new HTTPServletImpl(servletConfig, servletContext, servletConfig.getServletName()); // webroot String strWebroot=config.get("webroot"); if(StringUtil.isEmpty(strWebroot,true)) throw new IOException("missing webroot configuration"); Resource root=ResourcesImpl.getFileResourceProvider().getResource(strWebroot); root.mkdirs(); // serverName String serverName=config.get("server-name"); if(StringUtil.isEmpty(serverName,true))serverName="localhost"; // uri String strUri=config.get("uri"); if(StringUtil.isEmpty(strUri,true)) throw new IOException("missing uri configuration"); URI uri; try { uri = lucee.commons.net.HTTPUtil.toURI(strUri); } catch (URISyntaxException e) { throw Caster.toPageException(e); } // cookie Cookie[] cookies; String strCookie=config.get("cookie"); if(StringUtil.isEmpty(strCookie,true)) cookies=new Cookie[0]; else { Map<String,String> mapCookies=HTTPUtil.parseParameterList(strCookie,false,null); int index=0; cookies=new Cookie[mapCookies.size()]; Entry<String, String> entry; Iterator<Entry<String, String>> it = mapCookies.entrySet().iterator(); Cookie c; while(it.hasNext()){ entry = it.next(); c=ReqRspUtil.toCookie(entry.getKey(),entry.getValue(),null); if(c!=null)cookies[index++]=c; else throw new IOException("cookie name ["+entry.getKey()+"] is invalid"); } } // header Pair[] headers=new Pair[0]; // parameters Pair[] parameters=new Pair[0]; // attributes StructImpl attributes = new StructImpl(); ByteArrayOutputStream os=new ByteArrayOutputStream(); HttpServletRequestDummy req=new HttpServletRequestDummy( root,serverName,uri.getPath(),uri.getQuery(),cookies,headers,parameters,attributes,null,null); req.setProtocol("CLI/1.0"); HttpServletResponse rsp=new HttpServletResponseDummy(os); serviceCFML(servlet, req, rsp); String res = os.toString(ReqRspUtil.getCharacterEncoding(null,rsp).name()); System.out.println(res); } @Override public ServletConfig[] getServletConfigs(){ return servletConfigs.toArray(new ServletConfig[servletConfigs.size()]); } @Override public long uptime() { return uptime; } /*public Bundle getCoreBundle() { return bundle; }*/ @Override public BundleCollection getBundleCollection() { return bundleCollection; } @Override public BundleContext getBundleContext() { return bundleCollection.getBundleContext(); } @Override public ClassUtil getClassUtil() { return new ClassUtilImpl(); } @Override public ListUtil getListUtil() { return new ListUtilImpl(); } @Override public DBUtil getDBUtil() { return new DBUtilImpl(); } @Override public ORMUtil getORMUtil() { return new ORMUtilImpl(); } @Override public TemplateUtil getTemplateUtil() { return new TemplateUtilImpl(); } @Override public HTMLUtil getHTMLUtil() { return new HTMLUtilImpl(); } @Override public ScriptEngineFactory getScriptEngineFactory(int dialect) { if(dialect==CFMLEngine.DIALECT_CFML) { if(cfmlScriptEngine==null) cfmlScriptEngine=new ScriptEngineFactoryImpl(this,false,dialect); return cfmlScriptEngine; } if(luceeScriptEngine==null) luceeScriptEngine=new ScriptEngineFactoryImpl(this,false,dialect); return luceeScriptEngine; } @Override public ScriptEngineFactory getTagEngineFactory(int dialect) { if(dialect==CFMLEngine.DIALECT_CFML) { if(cfmlTagEngine==null) cfmlTagEngine=new ScriptEngineFactoryImpl(this,true,dialect); return cfmlTagEngine; } if(luceeTagEngine==null) luceeTagEngine=new ScriptEngineFactoryImpl(this,true,dialect); return luceeTagEngine; } @Override public PageContext createPageContext(File contextRoot, String host, String scriptName, String queryString , Cookie[] cookies,Map<String, Object> headers,Map<String, String> parameters, Map<String, Object> attributes, OutputStream os, long timeout, boolean register) throws ServletException { // FUTURE add first 2 arguments to interface return PageContextUtil.getPageContext(null,null,contextRoot,host, scriptName, queryString, cookies, headers, parameters, attributes, os,register,timeout,false); } @Override public ConfigWeb createConfig(File contextRoot,String host, String scriptName) throws ServletException { // TODO do a mored rect approach PageContext pc = null; try{ // FUTURE add first 2 arguments to interface pc = PageContextUtil.getPageContext(null,null,contextRoot,host,scriptName, null, null, null, null, null, null,false,-1,false); return pc.getConfig(); } finally{ pc.getConfig().getFactory().releaseLuceePageContext(pc, false); } } @Override public void releasePageContext(PageContext pc, boolean unregister) { PageContextUtil.releasePageContext(pc,unregister); } @Override public lucee.runtime.util.SystemUtil getSystemUtil() { return new SystemUtilImpl(); } @Override public TimeZone getThreadTimeZone() { return ThreadLocalPageContext.getTimeZone(); } @Override public Instrumentation getInstrumentation() { return InstrumentationFactory.getInstrumentation(ThreadLocalPageContext.getConfig()); } public Controler getControler() { return controler; } public void onStart(ConfigImpl config, boolean reload) { String context=config instanceof ConfigWeb?"Web":"Server"; if(!ThreadLocalPageContext.callOnStart.get()) return; Resource listenerTemplateLucee = config.getConfigDir().getRealResource("context/"+context+"."+lucee.runtime.config.Constants.getLuceeComponentExtension()); Resource listenerTemplateCFML = config.getConfigDir().getRealResource("context/"+context+"."+lucee.runtime.config.Constants.getCFMLComponentExtension()); // dialect int dialect; if(listenerTemplateLucee.isFile()) dialect=CFMLEngine.DIALECT_LUCEE; else if(listenerTemplateCFML.isFile()) dialect=CFMLEngine.DIALECT_CFML; else return; // we do not wait for this new OnStart(config, dialect,context, reload).start(); } private class OnStart extends Thread { private ConfigImpl config; private int dialect; private boolean reload; private String context; public OnStart(ConfigImpl config, int dialect, String context, boolean reload) { this.config=config; this.dialect=dialect; this.context=context; this.reload=reload; } public void run() { boolean isWeb=config instanceof ConfigWeb; String id=CreateUniqueId.invoke(); final String requestURI="/"+(isWeb?"lucee":"lucee-server")+"/"+context+"."+(dialect==CFMLEngine.DIALECT_LUCEE?lucee.runtime.config.Constants.getLuceeComponentExtension():lucee.runtime.config.Constants.getCFMLComponentExtension()); //PageContext oldPC = ThreadLocalPageContext.get(); PageContext pc=null; try { String remotePersisId; try { remotePersisId=Md5.getDigestAsString(requestURI+id); } catch (IOException e) { throw Caster.toPageException(e); } String queryString="method=on"+context+"Start&reload="+reload+"&"+ComponentPageImpl.REMOTE_PERSISTENT_ID+"="+remotePersisId; if(config instanceof ConfigWeb) { Pair[] headers = new Pair[]{new Pair<String,Object>("AMF-Forward","true")}; Struct attrs=new StructImpl(); attrs.setEL("client", "lucee-listener-1-0"); pc = ThreadUtil.createPageContext( (ConfigWeb)config, DevNullOutputStream.DEV_NULL_OUTPUT_STREAM, "localhost", requestURI,queryString, new Cookie[0], headers,null, new Pair[0], attrs,true,Long.MAX_VALUE); } else { Map<String, Object> headers=new HashMap<String, Object>(); headers.put("AMF-Forward","true"); Map<String, Object> attrs=new HashMap<String, Object>(); attrs.put("client", "lucee-listener-1-0"); File root = new File(config.getRootDirectory().getAbsolutePath()); CreationImpl cr =(CreationImpl)CreationImpl.getInstance(engine); ServletConfig sc = cr.createServletConfig(root, null, null); pc = PageContextUtil.getPageContext( config,sc,root, "localhost", requestURI, queryString, new Cookie[0], headers, null, attrs, DevNullOutputStream.DEV_NULL_OUTPUT_STREAM, true,Long.MAX_VALUE, Caster.toBooleanValue(SystemUtil.getSystemPropOrEnvVar("lucee.ignore.scopes", null),false)); } if(dialect==CFMLEngine.DIALECT_LUCEE) pc.execute(requestURI, true,false); else pc.executeCFML(requestURI, true,false); } catch(Throwable t) { // we simply ignore exceptions, if the template itself throws an error it will be handled by the error listener ExceptionUtil.rethrowIfNecessary(t); } finally { CFMLFactory f = pc.getConfig().getFactory(); f.releaseLuceePageContext(pc,true); //ThreadLocalPageContext.register(oldPC); } } } }