001 package railo.runtime.net.amf; 002 003 import java.io.ByteArrayOutputStream; 004 import java.io.IOException; 005 import java.io.OutputStream; 006 import java.util.ArrayList; 007 import java.util.List; 008 import java.util.Map; 009 010 import javax.servlet.ServletConfig; 011 import javax.servlet.ServletContext; 012 import javax.servlet.ServletException; 013 import javax.servlet.http.Cookie; 014 import javax.servlet.http.HttpServletRequest; 015 import javax.servlet.http.HttpServletResponse; 016 017 import railo.commons.io.DevNullOutputStream; 018 import railo.commons.io.res.Resource; 019 import railo.commons.lang.Pair; 020 import railo.commons.lang.SystemOut; 021 import railo.runtime.CFMLFactory; 022 import railo.runtime.PageContext; 023 import railo.runtime.PageContextImpl; 024 import railo.runtime.PageSource; 025 import railo.runtime.config.ConfigImpl; 026 import railo.runtime.config.ConfigWebImpl; 027 import railo.runtime.engine.CFMLEngineImpl; 028 import railo.runtime.exp.PageException; 029 import railo.runtime.net.http.HttpServletRequestDummy; 030 import railo.runtime.net.http.HttpServletResponseDummy; 031 import railo.runtime.net.http.HttpUtil; 032 import railo.runtime.net.http.ReqRspUtil; 033 import railo.runtime.op.Caster; 034 import railo.runtime.type.Collection; 035 import railo.runtime.type.KeyImpl; 036 import railo.runtime.type.Struct; 037 import railo.runtime.type.StructImpl; 038 import flex.messaging.config.ConfigMap; 039 040 public class CFMLProxy { 041 042 private static final Collection.Key FLASH = KeyImpl.intern("flash"); 043 private static final Collection.Key PARAMS = KeyImpl.intern("params"); 044 private static final Collection.Key RESULT = KeyImpl.intern("result"); 045 private static final Collection.Key AMF_FORWARD = KeyImpl.intern("AMF-Forward"); 046 047 048 049 public Object invokeBody(AMFCaster caster,ConfigMap configMap,ServletContext context,ServletConfig config,HttpServletRequest req, 050 HttpServletResponse rsp,String serviceName,String serviceMethodName,List rawParams) throws ServletException, PageException,IOException { 051 052 //try { 053 054 055 // Forward 056 CFMLFactory factory = CFMLEngineImpl.getInstance().getCFMLFactory(context, config, req); 057 PageContext pc=null; 058 059 // CFC Files 060 String cfc; 061 Object parameters=null; 062 try { 063 cfc="/"+serviceName.replace('.','/')+".cfc"; 064 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 065 pc=createPageContext(factory,cfc,"method="+serviceMethodName,baos,req); 066 PageSource source = ((PageContextImpl)pc).getPageSourceExisting(cfc); 067 068 if(caster==null)caster=((ConfigImpl)pc.getConfig()).getAMFCaster(configMap); 069 parameters=caster.toCFMLObject(rawParams); 070 if(source!=null) { 071 print(pc,cfc+"?method="+serviceMethodName); 072 // Map 073 //print.err(parameters); 074 if(parameters instanceof Map){ 075 //print.err("map"); 076 pc.getHttpServletRequest().setAttribute("argumentCollection", parameters); 077 } 078 // List 079 else if(parameters instanceof List){ 080 //print.err("list"); 081 pc.getHttpServletRequest().setAttribute("argumentCollection", parameters); 082 } 083 else { 084 ArrayList list = new ArrayList(); 085 list.add(parameters); 086 pc.getHttpServletRequest().setAttribute("argumentCollection", list); 087 088 } 089 090 // Execute 091 pc.execute(cfc,true); 092 093 // write back response 094 writeBackResponse(pc,rsp); 095 096 // After 097 return caster.toAMFObject(pc.variablesScope().get(AMF_FORWARD,null)); 098 099 } 100 } 101 finally { 102 if(pc!=null)factory.releaseRailoPageContext(pc); 103 } 104 105 // CFML Files 106 String cfml; 107 try { 108 cfml="/"+(serviceName.replace('.','/')+'/'+serviceMethodName.replace('.','/'))+".cfm"; 109 pc=createPageContext(factory,cfml,"",null,req); 110 PageSource source = ((PageContextImpl)pc).getPageSourceExisting(cfml); 111 112 if(source!=null) { 113 print(pc,cfml); 114 // Before 115 Struct params=new StructImpl(); 116 pc.variablesScope().setEL(FLASH,params); 117 params.setEL(PARAMS,parameters); 118 119 // Execute 120 pc.execute(cfml,true); 121 122 // write back response 123 writeBackResponse(pc,rsp); 124 125 // After 126 Object flash=pc.variablesScope().get(FLASH,null); 127 if(flash instanceof Struct) { 128 return caster.toAMFObject(((Struct)flash).get(RESULT,null)); 129 } 130 return null; 131 } 132 } 133 finally { 134 if(pc!=null)factory.releaseRailoPageContext(pc); 135 } 136 137 throw new AMFException("can't find cfml ("+cfml+") or cfc ("+cfc+") matching the request"); 138 } 139 140 private PageContext createPageContext(CFMLFactory factory,String scriptName,String queryString, OutputStream os, HttpServletRequest formerReq) { 141 Resource root = factory.getConfig().getRootDirectory(); 142 if(os==null)os=DevNullOutputStream.DEV_NULL_OUTPUT_STREAM; 143 144 // Request 145 HttpServletRequestDummy req = new HttpServletRequestDummy( 146 root,"localhost",scriptName,queryString, 147 ReqRspUtil.getCookies(factory.getConfig(),formerReq), 148 HttpUtil.cloneHeaders(formerReq), 149 HttpUtil.cloneParameters(formerReq), 150 HttpUtil.getAttributesAsStruct(formerReq),null); 151 req.addHeader("AMF-Forward", "true"); 152 HttpServletResponseDummy rsp = new HttpServletResponseDummy(os); 153 154 return factory.getRailoPageContext(factory.getServlet(), req, rsp, null, false, -1, false); 155 } 156 157 private void writeBackResponse(PageContext pc, HttpServletResponse rsp) { 158 HttpServletResponseDummy hsrd=(HttpServletResponseDummy) pc.getHttpServletResponse(); 159 160 // Cookie 161 Cookie[] cookies = hsrd.getCookies(); 162 if(cookies!=null) { 163 for(int i=0;i<cookies.length;i++) { 164 rsp.addCookie(cookies[i]); 165 } 166 } 167 168 // header 169 Pair[] headers = hsrd.getHeaders(); 170 Pair header ; 171 Object value; 172 if(headers!=null) { 173 for(int i=0;i<headers.length;i++) { 174 header=headers[i]; 175 value=header.getValue(); 176 if(value instanceof Long)rsp.addDateHeader(header.getName(), ((Long)value).longValue()); 177 else if(value instanceof Integer)rsp.addDateHeader(header.getName(), ((Integer)value).intValue()); 178 else rsp.addHeader(header.getName(), Caster.toString(header.getValue(),"")); 179 } 180 } 181 } 182 183 private void print(PageContext pc, String str) { 184 if(pc.getConfig() instanceof ConfigWebImpl) 185 SystemOut.printDate(((ConfigWebImpl)pc.getConfig()).getOutWriter(), str); 186 187 } 188 }