package railo.runtime.net.amf; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import railo.commons.io.DevNullOutputStream; import railo.commons.io.res.Resource; import railo.commons.lang.Pair; import railo.commons.lang.SystemOut; import railo.runtime.CFMLFactory; import railo.runtime.PageContext; import railo.runtime.PageContextImpl; import railo.runtime.PageSource; import railo.runtime.config.ConfigImpl; import railo.runtime.config.ConfigWebImpl; import railo.runtime.engine.CFMLEngineImpl; import railo.runtime.exp.PageException; import railo.runtime.net.http.HttpServletRequestDummy; import railo.runtime.net.http.HttpServletResponseDummy; import railo.runtime.net.http.HttpUtil; import railo.runtime.net.http.ReqRspUtil; import railo.runtime.op.Caster; import railo.runtime.type.Collection; import railo.runtime.type.KeyImpl; import railo.runtime.type.Struct; import railo.runtime.type.StructImpl; import flex.messaging.config.ConfigMap; public class CFMLProxy { private static final Collection.Key FLASH = KeyImpl.intern("flash"); private static final Collection.Key PARAMS = KeyImpl.intern("params"); private static final Collection.Key RESULT = KeyImpl.intern("result"); private static final Collection.Key AMF_FORWARD = KeyImpl.intern("AMF-Forward"); public Object invokeBody(AMFCaster caster,ConfigMap configMap,ServletContext context,ServletConfig config,HttpServletRequest req, HttpServletResponse rsp,String serviceName,String serviceMethodName,List rawParams) throws ServletException, PageException,IOException { //try { // Forward CFMLFactory factory = CFMLEngineImpl.getInstance().getCFMLFactory(context, config, req); PageContext pc=null; // CFC Files String cfc; Object parameters=null; try { cfc="/"+serviceName.replace('.','/')+".cfc"; ByteArrayOutputStream baos = new ByteArrayOutputStream(); pc=createPageContext(factory,cfc,"method="+serviceMethodName,baos,req); PageSource source = ((PageContextImpl)pc).getPageSourceExisting(cfc); if(caster==null)caster=((ConfigImpl)pc.getConfig()).getAMFCaster(configMap); parameters=caster.toCFMLObject(rawParams); if(source!=null) { print(pc,cfc+"?method="+serviceMethodName); // Map //print.err(parameters); if(parameters instanceof Map){ //print.err("map"); pc.getHttpServletRequest().setAttribute("argumentCollection", parameters); } // List else if(parameters instanceof List){ //print.err("list"); pc.getHttpServletRequest().setAttribute("argumentCollection", parameters); } else { ArrayList list = new ArrayList(); list.add(parameters); pc.getHttpServletRequest().setAttribute("argumentCollection", list); } // Execute pc.execute(cfc,true); // write back response writeBackResponse(pc,rsp); // After return caster.toAMFObject(pc.variablesScope().get(AMF_FORWARD,null)); } } finally { if(pc!=null)factory.releaseRailoPageContext(pc); } // CFML Files String cfml; try { cfml="/"+(serviceName.replace('.','/')+'/'+serviceMethodName.replace('.','/'))+".cfm"; pc=createPageContext(factory,cfml,"",null,req); PageSource source = ((PageContextImpl)pc).getPageSourceExisting(cfml); if(source!=null) { print(pc,cfml); // Before Struct params=new StructImpl(); pc.variablesScope().setEL(FLASH,params); params.setEL(PARAMS,parameters); // Execute pc.execute(cfml,true); // write back response writeBackResponse(pc,rsp); // After Object flash=pc.variablesScope().get(FLASH,null); if(flash instanceof Struct) { return caster.toAMFObject(((Struct)flash).get(RESULT,null)); } return null; } } finally { if(pc!=null)factory.releaseRailoPageContext(pc); } throw new AMFException("can't find cfml ("+cfml+") or cfc ("+cfc+") matching the request"); } private PageContext createPageContext(CFMLFactory factory,String scriptName,String queryString, OutputStream os, HttpServletRequest formerReq) { Resource root = factory.getConfig().getRootDirectory(); if(os==null)os=DevNullOutputStream.DEV_NULL_OUTPUT_STREAM; // Request HttpServletRequestDummy req = new HttpServletRequestDummy( root,"localhost",scriptName,queryString, ReqRspUtil.getCookies(factory.getConfig(),formerReq), HttpUtil.cloneHeaders(formerReq), HttpUtil.cloneParameters(formerReq), HttpUtil.getAttributesAsStruct(formerReq),null); req.addHeader("AMF-Forward", "true"); HttpServletResponseDummy rsp = new HttpServletResponseDummy(os); return factory.getRailoPageContext(factory.getServlet(), req, rsp, null, false, -1, false); } private void writeBackResponse(PageContext pc, HttpServletResponse rsp) { HttpServletResponseDummy hsrd=(HttpServletResponseDummy) pc.getHttpServletResponse(); // Cookie Cookie[] cookies = hsrd.getCookies(); if(cookies!=null) { for(int i=0;i<cookies.length;i++) { rsp.addCookie(cookies[i]); } } // header Pair<String,Object>[] headers = hsrd.getHeaders(); Pair<String,Object> header ; Object value; if(headers!=null) { for(int i=0;i<headers.length;i++) { header=headers[i]; value=header.getValue(); if(value instanceof Long)rsp.addDateHeader(header.getName(), ((Long)value).longValue()); else if(value instanceof Integer)rsp.addDateHeader(header.getName(), ((Integer)value).intValue()); else rsp.addHeader(header.getName(), Caster.toString(header.getValue(),"")); } } } private void print(PageContext pc, String str) { if(pc.getConfig() instanceof ConfigWebImpl) SystemOut.printDate(((ConfigWebImpl)pc.getConfig()).getOutWriter(), str); } }