001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.engine; 020 021import java.io.ByteArrayInputStream; 022import java.io.ByteArrayOutputStream; 023import java.io.IOException; 024import java.io.InputStream; 025import java.io.OutputStream; 026import java.net.MalformedURLException; 027import java.net.URI; 028import java.net.URISyntaxException; 029import java.net.URL; 030import java.util.ArrayList; 031import java.util.Iterator; 032import java.util.List; 033import java.util.Map; 034import java.util.Map.Entry; 035 036import javax.servlet.ServletConfig; 037import javax.servlet.ServletContext; 038import javax.servlet.ServletException; 039import javax.servlet.http.Cookie; 040import javax.servlet.http.HttpServlet; 041import javax.servlet.http.HttpServletRequest; 042import javax.servlet.http.HttpServletResponse; 043import javax.servlet.jsp.JspException; 044 045import lucee.cli.servlet.HTTPServletImpl; 046import lucee.commons.collection.MapFactory; 047import lucee.commons.io.CompressUtil; 048import lucee.commons.io.FileUtil; 049import lucee.commons.io.IOUtil; 050import lucee.commons.io.SystemUtil; 051import lucee.commons.io.res.Resource; 052import lucee.commons.io.res.ResourceProvider; 053import lucee.commons.io.res.ResourcesImpl; 054import lucee.commons.io.res.util.ResourceUtil; 055import lucee.commons.io.res.util.ResourceUtilImpl; 056import lucee.commons.lang.ExceptionUtil; 057import lucee.commons.lang.Pair; 058import lucee.commons.lang.StringUtil; 059import lucee.commons.lang.SystemOut; 060import lucee.commons.lang.types.RefBoolean; 061import lucee.commons.lang.types.RefBooleanImpl; 062import lucee.commons.net.HTTPUtil; 063import lucee.intergral.fusiondebug.server.FDControllerImpl; 064import lucee.loader.engine.CFMLEngine; 065import lucee.loader.engine.CFMLEngineFactory; 066import lucee.loader.engine.CFMLEngineWrapper; 067import lucee.loader.util.Util; 068import lucee.runtime.CFMLFactory; 069import lucee.runtime.CFMLFactoryImpl; 070import lucee.runtime.Info; 071import lucee.runtime.PageContext; 072import lucee.runtime.PageSource; 073import lucee.runtime.config.ConfigServer; 074import lucee.runtime.config.ConfigServerFactory; 075import lucee.runtime.config.ConfigServerImpl; 076import lucee.runtime.config.ConfigWeb; 077import lucee.runtime.config.ConfigWebFactory; 078import lucee.runtime.config.ConfigWebImpl; 079import lucee.runtime.config.ConfigWebUtil; 080import lucee.runtime.exp.ApplicationException; 081import lucee.runtime.exp.PageException; 082import lucee.runtime.exp.PageServletException; 083import lucee.runtime.net.http.HTTPServletRequestWrap; 084import lucee.runtime.net.http.HttpServletRequestDummy; 085import lucee.runtime.net.http.HttpServletResponseDummy; 086import lucee.runtime.net.http.ReqRspUtil; 087import lucee.runtime.op.CastImpl; 088import lucee.runtime.op.Caster; 089import lucee.runtime.op.CreationImpl; 090import lucee.runtime.op.DecisionImpl; 091import lucee.runtime.op.ExceptonImpl; 092import lucee.runtime.op.OperationImpl; 093import lucee.runtime.type.StructImpl; 094import lucee.runtime.util.BlazeDSImpl; 095import lucee.runtime.util.Cast; 096import lucee.runtime.util.Creation; 097import lucee.runtime.util.Decision; 098import lucee.runtime.util.Excepton; 099import lucee.runtime.util.HTTPUtilImpl; 100import lucee.runtime.util.Operation; 101import lucee.runtime.util.ZipUtil; 102import lucee.runtime.util.ZipUtilImpl; 103import lucee.runtime.video.VideoUtil; 104import lucee.runtime.video.VideoUtilImpl; 105 106import com.intergral.fusiondebug.server.FDControllerFactory; 107 108/** 109 * The CFMl Engine 110 */ 111public final class CFMLEngineImpl implements CFMLEngine { 112 113 114 private static Map<String,CFMLFactory> initContextes=MapFactory.<String,CFMLFactory>getConcurrentMap(); 115 private static Map<String,CFMLFactory> contextes=MapFactory.<String,CFMLFactory>getConcurrentMap(); 116 private ConfigServerImpl configServer=null; 117 private static CFMLEngineImpl engine=null; 118 //private ServletConfig config; 119 private CFMLEngineFactory factory; 120 private AMFEngine amfEngine=new AMFEngine(); 121 private final RefBoolean controlerState=new RefBooleanImpl(true); 122 private boolean allowRequestTimeout=true; 123 private Monitor monitor; 124 private List<ServletConfig> servletConfigs=new ArrayList<ServletConfig>(); 125 private long uptime; 126 127 128 //private static CFMLEngineImpl engine=new CFMLEngineImpl(); 129 130 private CFMLEngineImpl(CFMLEngineFactory factory) { 131 this.factory=factory; 132 CFMLEngineFactory.registerInstance(this);// patch, not really good but it works 133 ConfigServerImpl cs = getConfigServerImpl(); 134 135 SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT),"Start CFML Controller"); 136 Controler controler = new Controler(cs,initContextes,5*1000,controlerState); 137 controler.setDaemon(true); 138 controler.setPriority(Thread.MIN_PRIORITY); 139 controler.start(); 140 141 touchMonitor(cs); 142 this.uptime=System.currentTimeMillis(); 143 //this.config=config; 144 } 145 146 147 public void touchMonitor(ConfigServerImpl cs) { 148 if(monitor!=null && monitor.isAlive()) return; 149 monitor = new Monitor(cs,controlerState); 150 monitor.setDaemon(true); 151 monitor.setPriority(Thread.MIN_PRIORITY); 152 monitor.start(); 153 } 154 155 /** 156 * get singelton instance of the CFML Engine 157 * @param factory 158 * @return CFMLEngine 159 */ 160 public static synchronized CFMLEngine getInstance(CFMLEngineFactory factory) { 161 if(engine==null) { 162 engine=new CFMLEngineImpl(factory); 163 } 164 return engine; 165 } 166 167 /** 168 * get singelton instance of the CFML Engine, throwsexception when not already init 169 * @param factory 170 * @return CFMLEngine 171 */ 172 public static synchronized CFMLEngine getInstance() throws ServletException { 173 if(engine!=null) return engine; 174 throw new ServletException("CFML Engine is not loaded"); 175 } 176 177 @Override 178 public void addServletConfig(ServletConfig config) throws ServletException { 179 servletConfigs.add(config); 180 String real=ReqRspUtil.getRootPath(config.getServletContext()); 181 if(!initContextes.containsKey(real)) { 182 CFMLFactory jspFactory = loadJSPFactory(getConfigServerImpl(),config,initContextes.size()); 183 initContextes.put(real,jspFactory); 184 } 185 } 186 187 // FUTURE add to public interface 188 public ConfigServer getConfigServer(String password) throws PageException { 189 getConfigServerImpl().checkAccess(password); 190 return configServer; 191 } 192 193 // FUTURE add to public interface 194 public ConfigServer getConfigServer(String key, long timeNonce) throws PageException { 195 getConfigServerImpl().checkAccess(key,timeNonce); 196 return configServer; 197 } 198 199 public void setConfigServerImpl(ConfigServerImpl cs) { 200 this.configServer=cs; 201 } 202 203 private ConfigServerImpl getConfigServerImpl() { 204 if(configServer==null) { 205 try { 206 ResourceProvider frp = ResourcesImpl.getFileResourceProvider(); 207 Resource context = frp.getResource(factory.getResourceRoot().getAbsolutePath()).getRealResource("context"); 208 //CFMLEngineFactory.registerInstance(this);// patch, not really good but it works 209 configServer=ConfigServerFactory.newInstance( 210 this, 211 initContextes, 212 contextes, 213 context); 214 } catch (Exception e) { 215 e.printStackTrace(); 216 } 217 } 218 return configServer; 219 } 220 221 private CFMLFactoryImpl loadJSPFactory(ConfigServerImpl configServer, ServletConfig sg, int countExistingContextes) throws ServletException { 222 try { 223 // Load Config 224 RefBoolean isCustomSetting=new RefBooleanImpl(); 225 Resource configDir=getConfigDirectory(sg,configServer,countExistingContextes,isCustomSetting); 226 227 CFMLFactoryImpl factory=new CFMLFactoryImpl(this); 228 ConfigWebImpl config=ConfigWebFactory.newInstance(factory,configServer,configDir,isCustomSetting.toBooleanValue(),sg); 229 factory.setConfig(config); 230 return factory; 231 } 232 catch (Exception e) { 233 ServletException se= new ServletException(e.getMessage()); 234 se.setStackTrace(e.getStackTrace()); 235 throw se; 236 } 237 238 } 239 240 /** 241 * loads Configuration File from System, from init Parameter from web.xml 242 * @param sg 243 * @param configServer 244 * @param countExistingContextes 245 * @return return path to directory 246 */ 247 private Resource getConfigDirectory(ServletConfig sg, ConfigServerImpl configServer, int countExistingContextes, RefBoolean isCustomSetting) throws PageServletException { 248 isCustomSetting.setValue(true); 249 ServletContext sc=sg.getServletContext(); 250 String strConfig=sg.getInitParameter("configuration"); 251 if(strConfig==null)strConfig=sg.getInitParameter("lucee-web-directory"); 252 if(strConfig==null)strConfig=sg.getInitParameter("railo-web-directory"); 253 if(strConfig==null) { 254 isCustomSetting.setValue(false); 255 strConfig="{web-root-directory}/WEB-INF/lucee/"; 256 } 257 // only for backward compatibility 258 else if(strConfig.startsWith("/WEB-INF/railo/")) { 259 strConfig="{web-root-directory}"+strConfig; 260 strConfig=strConfig.replace("/railo/", "/lucee/"); 261 } 262 263 264 strConfig=Util.removeQuotes(strConfig,true); 265 266 267 268 // static path is not allowed 269 if(countExistingContextes>1 && strConfig!=null && strConfig.indexOf('{')==-1){ 270 String text="static path ["+strConfig+"] for servlet init param [lucee-web-directory] is not allowed, path must use a web-context specific placeholder."; 271 System.err.println(text); 272 throw new PageServletException(new ApplicationException(text)); 273 } 274 strConfig=SystemUtil.parsePlaceHolder(strConfig,sc,configServer.getLabels()); 275 276 277 278 ResourceProvider frp = ResourcesImpl.getFileResourceProvider(); 279 Resource root = frp.getResource(ReqRspUtil.getRootPath(sc)); 280 Resource configDir=ResourceUtil.createResource(root.getRealResource(strConfig), FileUtil.LEVEL_PARENT_FILE,FileUtil.TYPE_DIR); 281 282 if(configDir==null) { 283 configDir=ResourceUtil.createResource(frp.getResource(strConfig), FileUtil.LEVEL_GRAND_PARENT_FILE,FileUtil.TYPE_DIR); 284 } 285 if(configDir==null) throw new PageServletException(new ApplicationException("path ["+strConfig+"] is invalid")); 286 287 if(!configDir.exists() || ResourceUtil.isEmptyDirectory(configDir, null)){ 288 Resource railoRoot; 289 // there is a railo directory 290 if(configDir.getName().equals("lucee") && (railoRoot=configDir.getParentResource().getRealResource("railo")).isDirectory()) { 291 try { 292 copyRecursiveAndRename(railoRoot,configDir); 293 } 294 catch (IOException e) { 295 try { 296 configDir.createDirectory(true); 297 } 298 catch (IOException ioe) {} 299 return configDir; 300 } 301 // zip the railo-server di and delete it (optional) 302 try { 303 Resource p=railoRoot.getParentResource(); 304 CompressUtil.compress(CompressUtil.FORMAT_ZIP, railoRoot, p.getRealResource("railo-web-context-old.zip"), false, -1); 305 ResourceUtil.removeEL(railoRoot, true); 306 } 307 catch(Throwable t){ 308 ExceptionUtil.rethrowIfNecessary(t); 309 t.printStackTrace(); 310 } 311 } 312 else { 313 try { 314 configDir.createDirectory(true); 315 } 316 catch (IOException e) {} 317 318 } 319 320 } 321 322 return configDir; 323 } 324 325 private static void copyRecursiveAndRename(Resource src,Resource trg) throws IOException { 326 if(!src.exists()) return ; 327 if(src.isDirectory()) { 328 if(!trg.exists())trg.mkdirs(); 329 330 Resource[] files = src.listResources(); 331 for(int i=0;i<files.length;i++) { 332 copyRecursiveAndRename(files[i],trg.getRealResource(files[i].getName())); 333 } 334 } 335 else if(src.isFile()) { 336 if(trg.getName().endsWith(".rc") || trg.getName().startsWith(".")) { 337 return; 338 } 339 340 if(trg.getName().equals("railo-web.xml.cfm")) { 341 trg=trg.getParentResource().getRealResource("lucee-web.xml.cfm"); 342 // cfLuceeConfiguration 343 InputStream is = src.getInputStream(); 344 OutputStream os = trg.getOutputStream(); 345 try{ 346 String str=Util.toString(is); 347 str=str.replace("<cfRailoConfiguration", "<!-- copy from Railo context --><cfLuceeConfiguration"); 348 str=str.replace("</cfRailoConfiguration", "</cfLuceeConfiguration"); 349 str=str.replace("<railo-configuration", "<lucee-configuration"); 350 str=str.replace("</railo-configuration", "</lucee-configuration"); 351 str=str.replace("{railo-config}", "{lucee-config}"); 352 str=str.replace("{railo-server}", "{lucee-server}"); 353 str=str.replace("{railo-web}", "{lucee-web}"); 354 str=str.replace("\"railo.commons.", "\"lucee.commons."); 355 str=str.replace("\"railo.runtime.", "\"lucee.runtime."); 356 str=str.replace("\"railo.cfx.", "\"lucee.cfx."); 357 str=str.replace("/railo-context.ra", "/lucee-context.lar"); 358 str=str.replace("/railo-context", "/lucee"); 359 str=str.replace("railo-server-context", "lucee-server"); 360 str=str.replace("http://www.getrailo.org", "http://stable.lucee.org"); 361 str=str.replace("http://www.getrailo.com", "http://stable.lucee.org"); 362 363 364 ByteArrayInputStream bais = new ByteArrayInputStream(str.getBytes()); 365 366 try { 367 Util.copy(bais, os); 368 bais.close(); 369 } 370 finally { 371 Util.closeEL(is, os); 372 } 373 } 374 finally { 375 Util.closeEL(is,os); 376 } 377 return; 378 } 379 380 InputStream is = src.getInputStream(); 381 OutputStream os = trg.getOutputStream(); 382 try{ 383 Util.copy(is, os); 384 } 385 finally { 386 Util.closeEL(is, os); 387 } 388 } 389 } 390 391 392 393 @Override 394 395 public CFMLFactory getCFMLFactory(ServletContext srvContext, ServletConfig srvConfig,HttpServletRequest req) throws ServletException { 396 String real=ReqRspUtil.getRootPath(srvContext); 397 ConfigServerImpl cs = getConfigServerImpl(); 398 399 400 // Load JspFactory 401 CFMLFactoryImpl factory=null; 402 Object o=contextes.get(real); 403 if(o==null) { 404 //int size=sn.getContextCount(); 405 //if(size!=-1 && size <= contextes.size()) 406 //throw new ServletException("the maximum size of "+size+" web contextes is reached, " +"to have more contexes upgrade your lucee version, already contextes in use are ["+getContextList()+"]"); 407 o=initContextes.get(real); 408 if(o!=null) { 409 factory=(CFMLFactoryImpl) o; 410 } 411 else { 412 factory=loadJSPFactory(cs,srvConfig,initContextes.size()); 413 initContextes.put(real,factory); 414 } 415 contextes.put(real,factory); 416 417 try { 418 String cp = req.getContextPath(); 419 if(cp==null)cp=""; 420 factory.setURL(new URL(req.getScheme(),req.getServerName(),req.getServerPort(),cp)); 421 } 422 catch (MalformedURLException e) { 423 e.printStackTrace(); 424 } 425 // 426 427 } 428 else { 429 factory=(CFMLFactoryImpl) o; 430 } 431 return factory; 432 } 433 434 @Override 435 public void serviceCFML(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException { 436 437 CFMLFactory factory=getCFMLFactory(servlet.getServletContext(), servlet.getServletConfig(), req); 438 439 PageContext pc = factory.getLuceePageContext(servlet,req,rsp,null,false,-1,false); 440 ThreadQueue queue = factory.getConfig().getThreadQueue(); 441 queue.enter(pc); 442 try { 443 /*print.out("INCLUDE"); 444 print.out("servlet_path:"+req.getAttribute("javax.servlet.include.servlet_path")); 445 print.out("request_uri:"+req.getAttribute("javax.servlet.include.request_uri")); 446 print.out("context_path:"+req.getAttribute("javax.servlet.include.context_path")); 447 print.out("path_info:"+req.getAttribute("javax.servlet.include.path_info")); 448 print.out("query_string:"+req.getAttribute("javax.servlet.include.query_string")); 449 print.out("FORWARD"); 450 print.out("servlet_path:"+req.getAttribute("javax.servlet.forward.servlet_path")); 451 print.out("request_uri:"+req.getAttribute("javax.servlet.forward.request_uri")); 452 print.out("context_path:"+req.getAttribute("javax.servlet.forward.context_path")); 453 print.out("path_info:"+req.getAttribute("javax.servlet.forward.path_info")); 454 print.out("query_string:"+req.getAttribute("javax.servlet.forward.query_string")); 455 print.out("---"); 456 print.out(req.getServletPath()); 457 print.out(pc.getHttpServletRequest().getServletPath()); 458 */ 459 460 pc.execute(pc.getHttpServletRequest().getServletPath(),false); 461 } 462 catch (PageException pe) { 463 throw new PageServletException(pe); 464 } 465 finally { 466 queue.exit(pc); 467 factory.releaseLuceePageContext(pc); 468 FDControllerFactory.notifyPageComplete(); 469 } 470 } 471 472 public void serviceFile(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException { 473 req=new HTTPServletRequestWrap(req); 474 CFMLFactory factory=getCFMLFactory(servlet.getServletContext(), servlet.getServletConfig(), req); 475 ConfigWeb config = factory.getConfig(); 476 PageSource ps = config.getPageSourceExisting(null, null, req.getServletPath(), false, true, true, false); 477 //Resource res = ((ConfigWebImpl)config).getPhysicalResourceExistingX(null, null, req.getServletPath(), false, true, true); 478 479 if(ps==null) { 480 rsp.sendError(404); 481 } 482 else { 483 Resource res = ps.getResource(); 484 if(res==null) { 485 rsp.sendError(404); 486 } 487 else { 488 ReqRspUtil.setContentLength(rsp,res.length()); 489 String mt = servlet.getServletContext().getMimeType(req.getServletPath()); 490 if(!StringUtil.isEmpty(mt))rsp.setContentType(mt); 491 IOUtil.copy(res, rsp.getOutputStream(), true); 492 } 493 } 494 } 495 496 497 public void serviceRest(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException { 498 req=new HTTPServletRequestWrap(req); 499 CFMLFactory factory=getCFMLFactory(servlet.getServletContext(), servlet.getServletConfig(), req); 500 501 PageContext pc = factory.getLuceePageContext(servlet,req,rsp,null,false,-1,false); 502 ThreadQueue queue = factory.getConfig().getThreadQueue(); 503 queue.enter(pc); 504 try { 505 pc.executeRest(pc.getHttpServletRequest().getServletPath(),false); 506 } 507 catch (PageException pe) { 508 throw new PageServletException(pe); 509 } 510 finally { 511 queue.exit(pc); 512 factory.releaseLuceePageContext(pc); 513 FDControllerFactory.notifyPageComplete(); 514 } 515 516 517 } 518 519 520 /*private String getContextList() { 521 return List.arrayToList((String[])contextes.keySet().toArray(new String[contextes.size()]),", "); 522 }*/ 523 524 @Override 525 public String getVersion() { 526 return Info.getVersionAsString(); 527 } 528 529 @Override 530 public String getUpdateType() { 531 return getConfigServerImpl().getUpdateType(); 532 } 533 534 @Override 535 public URL getUpdateLocation() { 536 return getConfigServerImpl().getUpdateLocation(); 537 } 538 539 @Override 540 public boolean can(int type, String password) { 541 return getConfigServerImpl().passwordEqual(password); 542 } 543 544 public CFMLEngineFactory getCFMLEngineFactory() { 545 return factory; 546 } 547 548 public void serviceAMF(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException { 549 req=new HTTPServletRequestWrap(req); 550 amfEngine.service(servlet,req,rsp); 551 } 552 553 @Override 554 public void reset() { 555 reset(null); 556 } 557 558 @Override 559 public void reset(String configId) { 560 561 CFMLFactoryImpl cfmlFactory; 562 //ScopeContext scopeContext; 563 try { 564 Iterator<String> it = contextes.keySet().iterator(); 565 while(it.hasNext()) { 566 try { 567 cfmlFactory=(CFMLFactoryImpl) contextes.get(it.next()); 568 if(configId!=null && !configId.equals(cfmlFactory.getConfigWebImpl().getId())) continue; 569 570 // scopes 571 try{ 572 cfmlFactory.getScopeContext().clear(); 573 }catch(Throwable t){ 574 ExceptionUtil.rethrowIfNecessary(t); 575 t.printStackTrace(); 576 } 577 578 // PageContext 579 try{ 580 cfmlFactory.resetPageContext(); 581 }catch(Throwable t){ 582 ExceptionUtil.rethrowIfNecessary(t); 583 t.printStackTrace(); 584 } 585 586 // Query Cache 587 try{ 588 PageContext pc = ThreadLocalPageContext.get(); 589 if(pc!=null) { 590 ConfigWebUtil.getCacheHandlerFactories(pc.getConfig()).query.clear(pc); 591 ConfigWebUtil.getCacheHandlerFactories(pc.getConfig()).function.clear(pc); 592 ConfigWebUtil.getCacheHandlerFactories(pc.getConfig()).include.clear(pc); 593 } 594 //cfmlFactory.getDefaultQueryCache().clear(null); 595 }catch(Throwable t){ 596 ExceptionUtil.rethrowIfNecessary(t); 597 t.printStackTrace(); 598 } 599 600 // Gateway 601 try{ cfmlFactory.getConfigWebImpl().getGatewayEngine().reset();}catch(Throwable t){ExceptionUtil.rethrowIfNecessary(t);t.printStackTrace();} 602 603 } 604 catch(Throwable t){ 605 ExceptionUtil.rethrowIfNecessary(t); 606 t.printStackTrace(); 607 } 608 } 609 } 610 finally { 611 // Controller 612 controlerState.setValue(false); 613 } 614 } 615 616 @Override 617 public Cast getCastUtil() { 618 return CastImpl.getInstance(); 619 } 620 621 @Override 622 public Operation getOperatonUtil() { 623 return OperationImpl.getInstance(); 624 } 625 626 @Override 627 public Decision getDecisionUtil() { 628 return DecisionImpl.getInstance(); 629 } 630 631 @Override 632 public Excepton getExceptionUtil() { 633 return ExceptonImpl.getInstance(); 634 } 635 636 @Override 637 public Creation getCreationUtil() { 638 return CreationImpl.getInstance(this); 639 } 640 641 @Override 642 public Object getBlazeDSUtil() { 643 return new BlazeDSImpl(); 644 } 645 646 @Override 647 public Object getFDController() { 648 engine.allowRequestTimeout(false); 649 650 return new FDControllerImpl(engine,engine.getConfigServerImpl().getSerialNumber()); 651 } 652 653 public Map<String,CFMLFactory> getCFMLFactories() { 654 return initContextes; 655 } 656 657 @Override 658 public lucee.runtime.util.ResourceUtil getResourceUtil() { 659 return ResourceUtilImpl.getInstance(); 660 } 661 662 @Override 663 public lucee.runtime.util.HTTPUtil getHTTPUtil() { 664 return HTTPUtilImpl.getInstance(); 665 } 666 667 @Override 668 public PageContext getThreadPageContext() { 669 return ThreadLocalPageContext.get(); 670 } 671 672 @Override 673 public void registerThreadPageContext(PageContext pc) { 674 ThreadLocalPageContext.register(pc); 675 } 676 677 @Override 678 public VideoUtil getVideoUtil() { 679 return VideoUtilImpl.getInstance(); 680 } 681 682 @Override 683 public ZipUtil getZipUtil() { 684 return ZipUtilImpl.getInstance(); 685 } 686 687 @Override 688 public String getState() { 689 return Info.getStateAsString(); 690 } 691 692 public void allowRequestTimeout(boolean allowRequestTimeout) { 693 this.allowRequestTimeout=allowRequestTimeout; 694 } 695 696 public boolean allowRequestTimeout() { 697 return allowRequestTimeout; 698 } 699 700 public boolean isRunning() { 701 try{ 702 CFMLEngine other = CFMLEngineFactory.getInstance(); 703 // FUTURE patch, do better impl when changing loader 704 if(other!=this && controlerState.toBooleanValue() && !(other instanceof CFMLEngineWrapper)) { 705 SystemOut.printDate("CFMLEngine is still set to true but no longer valid, Lucee disable this CFMLEngine."); 706 controlerState.setValue(false); 707 reset(); 708 return false; 709 } 710 } 711 catch(Throwable t){ 712 ExceptionUtil.rethrowIfNecessary(t); 713 } 714 return controlerState.toBooleanValue(); 715 } 716 717 @Override 718 public void cli(Map<String, String> config, ServletConfig servletConfig) throws IOException,JspException,ServletException { 719 ServletContext servletContext = servletConfig.getServletContext(); 720 HTTPServletImpl servlet=new HTTPServletImpl(servletConfig, servletContext, servletConfig.getServletName()); 721 722 // webroot 723 String strWebroot=config.get("webroot"); 724 if(Util.isEmpty(strWebroot,true)) throw new IOException("missing webroot configuration"); 725 Resource root=ResourcesImpl.getFileResourceProvider().getResource(strWebroot); 726 root.mkdirs(); 727 728 // serverName 729 String serverName=config.get("server-name"); 730 if(Util.isEmpty(serverName,true))serverName="localhost"; 731 732 // uri 733 String strUri=config.get("uri"); 734 if(Util.isEmpty(strUri,true)) throw new IOException("missing uri configuration"); 735 URI uri; 736 try { 737 uri = lucee.commons.net.HTTPUtil.toURI(strUri); 738 } catch (URISyntaxException e) { 739 throw Caster.toPageException(e); 740 } 741 742 // cookie 743 Cookie[] cookies; 744 String strCookie=config.get("cookie"); 745 if(Util.isEmpty(strCookie,true)) cookies=new Cookie[0]; 746 else { 747 Map<String,String> mapCookies=HTTPUtil.parseParameterList(strCookie,false,null); 748 int index=0; 749 cookies=new Cookie[mapCookies.size()]; 750 Entry<String, String> entry; 751 Iterator<Entry<String, String>> it = mapCookies.entrySet().iterator(); 752 Cookie c; 753 while(it.hasNext()){ 754 entry = it.next(); 755 c=ReqRspUtil.toCookie(entry.getKey(),entry.getValue(),null); 756 if(c!=null)cookies[index++]=c; 757 else throw new IOException("Cookie name ["+entry.getKey()+"] is invalid"); 758 } 759 } 760 761 762 // header 763 Pair[] headers=new Pair[0]; 764 765 // parameters 766 Pair[] parameters=new Pair[0]; 767 768 // attributes 769 StructImpl attributes = new StructImpl(); 770 ByteArrayOutputStream os=new ByteArrayOutputStream(); 771 772 773 774 775 HttpServletRequestDummy req=new HttpServletRequestDummy( 776 root,serverName,uri.getPath(),uri.getQuery(),cookies,headers,parameters,attributes,null); 777 req.setProtocol("CLI/1.0"); 778 HttpServletResponse rsp=new HttpServletResponseDummy(os); 779 780 serviceCFML(servlet, req, rsp); 781 String res = os.toString(ReqRspUtil.getCharacterEncoding(null,rsp).name()); 782 System.out.println(res); 783 } 784 785 public ServletConfig[] getServletConfigs(){ 786 return servletConfigs.toArray(new ServletConfig[servletConfigs.size()]); 787 } 788 789 // FUTURE add to interface 790 public long uptime() { 791 return uptime; 792 } 793 794}