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.type.scope; 020 021import java.net.InetAddress; 022import java.net.UnknownHostException; 023import java.util.Enumeration; 024import java.util.HashMap; 025import java.util.Iterator; 026import java.util.Map; 027 028import javax.servlet.http.HttpServletRequest; 029 030import lucee.commons.lang.ExceptionUtil; 031import lucee.commons.lang.StringUtil; 032import lucee.runtime.PageContext; 033import lucee.runtime.config.NullSupportHelper; 034import lucee.runtime.dump.DumpData; 035import lucee.runtime.dump.DumpProperties; 036import lucee.runtime.engine.ThreadLocalPageContext; 037import lucee.runtime.listener.ApplicationContext; 038import lucee.runtime.net.http.ReqRspUtil; 039import lucee.runtime.op.Caster; 040import lucee.runtime.security.ScriptProtect; 041import lucee.runtime.type.Collection; 042import lucee.runtime.type.KeyImpl; 043import lucee.runtime.type.ReadOnlyStruct; 044import lucee.runtime.type.Struct; 045import lucee.runtime.type.StructImpl; 046import lucee.runtime.type.it.EntryIterator; 047import lucee.runtime.type.it.KeyIterator; 048import lucee.runtime.type.it.StringIterator; 049import lucee.runtime.type.util.KeyConstants; 050import lucee.runtime.type.util.StructUtil; 051 052/** 053 * 054 * 055 * To change the template for this generated type comment go to 056 * Window - Preferences - Java - Code Generation - Code and Comments 057 */ 058public final class CGIImplReadOnly extends ReadOnlyStruct implements CGI,ScriptProtected { 059 060 private static final long serialVersionUID = 5219795840777155232L; 061 062 private static final Collection.Key[] keys={ 063 KeyConstants._auth_password, KeyConstants._auth_type, KeyConstants._auth_user, KeyConstants._cert_cookie, KeyConstants._cert_flags, 064 KeyConstants._cert_issuer, KeyConstants._cert_keysize, KeyConstants._cert_secretkeysize, KeyConstants._cert_serialnumber, 065 KeyConstants._cert_server_issuer, KeyConstants._cert_server_subject, KeyConstants._cert_subject,KeyConstants._cf_template_path, 066 KeyConstants._content_length, KeyConstants._content_type, KeyConstants._gateway_interface, KeyConstants._http_accept, 067 KeyConstants._http_accept_encoding, KeyConstants._http_accept_language, KeyConstants._http_connection, KeyConstants._http_cookie, 068 KeyConstants._http_host, KeyConstants._http_user_agent, KeyConstants._http_referer, KeyConstants._https, KeyConstants._https_keysize, 069 KeyConstants._https_secretkeysize, KeyConstants._https_server_issuer, KeyConstants._https_server_subject, KeyConstants._path_info, 070 KeyConstants._path_translated, KeyConstants._query_string, KeyConstants._remote_addr, KeyConstants._remote_host, KeyConstants._remote_user, 071 KeyConstants._request_method, KeyConstants._request_url, KeyConstants._script_name, KeyConstants._server_name, KeyConstants._server_port, KeyConstants._server_port_secure, 072 KeyConstants._server_protocol, KeyConstants._server_software, KeyConstants._web_server_api, KeyConstants._context_path, KeyConstants._local_addr, 073 KeyConstants._local_host 074 }; 075 private static Struct staticKeys=new StructImpl(); 076 static{ 077 for(int i=0;i<keys.length;i++){ 078 staticKeys.setEL(keys[i],""); 079 } 080 } 081 082 private static String localAddress=""; 083 private static String localHost=""; 084 085 static { 086 try { 087 InetAddress addr = InetAddress.getLocalHost(); 088 localAddress=addr.getHostAddress(); 089 localHost=addr.getHostName(); 090 } 091 catch(UnknownHostException uhe) {} 092 } 093 094 private HttpServletRequest req; 095 private boolean isInit; 096 //private PageContext pc; 097 private Struct https; 098 private Struct headers; 099 private int scriptProtected; 100 101 private boolean disconnected; 102 private Map<Key, Object> disconnectedData; 103 104 public CGIImplReadOnly(){ 105 this.setReadOnly(true); 106 } 107 108 109 public void disconnect() { 110 if(disconnected) return; 111 112 disconnectedData=new HashMap<Key, Object>(); 113 for(int i=0;i<keys.length;i++){ 114 disconnectedData.put(keys[i], get(keys[i], "")); 115 } 116 req=null; 117 } 118 119 120 @Override 121 public boolean containsKey(Key key) { 122 return staticKeys.containsKey(key); 123 } 124 125 @Override 126 public boolean containsValue(Object value) { 127 // TODO Auto-generated method stub 128 return super.containsValue(value); 129 } 130 @Override 131 public Collection duplicate(boolean deepCopy) { 132 Struct sct=new StructImpl(); 133 copy(this,sct,deepCopy); 134 return sct; 135 } 136 137 138 @Override 139 public int size() { 140 return keys.length; 141 } 142 143 public Collection.Key[] keys() { 144 return keys; 145 } 146 147 @Override 148 public Object get(Collection.Key key, Object defaultValue) { 149 150 if(https==null) { 151 https=new StructImpl(); 152 headers=new StructImpl(); 153 String k,v; 154 try { 155 Enumeration e = req.getHeaderNames(); 156 157 while(e.hasMoreElements()) { 158 k = (String)e.nextElement(); 159 v = req.getHeader(k); 160 //print.err(k.length()+":"+k); 161 headers.setEL(KeyImpl.init(k),v); 162 headers.setEL(KeyImpl.init(k=k.replace('-','_')),v); 163 https.setEL(KeyImpl.init("http_"+k),v); 164 } 165 } 166 catch(Throwable t){ 167 ExceptionUtil.rethrowIfNecessary(t); 168 t.printStackTrace(); 169 } 170 } 171 172 String lkey=key.getLowerString(); 173 174 175 if(lkey.length()>7) { 176 char first=lkey.charAt(0); 177 if(first=='a') { 178 if(key.equals(KeyConstants._auth_type)) return toString(req.getAuthType()); 179 } 180 else if(first=='c') { 181 if(key.equals(KeyConstants._context_path))return toString(req.getContextPath()); 182 if(key.equals(KeyConstants._cf_template_path)) return getPathTranslated(); 183 } 184 else if(first=='h') { 185 if(lkey.startsWith("http_")){ 186 Object o = https.get(key,NullSupportHelper.NULL()); 187 if(o==NullSupportHelper.NULL() && key.equals(KeyConstants._http_if_modified_since)) 188 o = https.get(KeyConstants._last_modified,NullSupportHelper.NULL()); 189 if(o!=NullSupportHelper.NULL())return doScriptProtect((String)o); 190 } 191 } 192 else if(first=='r') { 193 if(key.equals(KeyConstants._remote_user)) return toString(req.getRemoteUser()); 194 if(key.equals(KeyConstants._remote_addr)) { 195 return toString(req.getRemoteAddr()); 196 } 197 if(key.equals(KeyConstants._remote_host)) return toString(req.getRemoteHost()); 198 if(key.equals(KeyConstants._request_method)) return req.getMethod(); 199 if(key.equals(KeyConstants._request_url)) return ReqRspUtil.getRequestURL( req, true ); 200 if(key.equals(KeyConstants._request_uri)) return toString(req.getAttribute("javax.servlet.include.request_uri")); 201 if(key.getUpperString().startsWith("REDIRECT_")){ 202 // from attributes (key sensitive) 203 Object value = req.getAttribute(key.getString()); 204 if(!StringUtil.isEmpty(value)) return toString(value); 205 206 // from attributes (key insensitive) 207 Enumeration<String> names = req.getAttributeNames(); 208 String k; 209 while(names.hasMoreElements()){ 210 k=names.nextElement(); 211 if(k.equalsIgnoreCase(key.getString())) { 212 return toString(req.getAttribute(k)); 213 } 214 } 215 } 216 } 217 218 219 else if(first=='l') { 220 if(key.equals(KeyConstants._local_addr)) return toString(localAddress); 221 if(key.equals(KeyConstants._local_host)) return toString(localHost); 222 } 223 else if(first=='s') { 224 if(key.equals(KeyConstants._script_name)) 225 return ReqRspUtil.getScriptName(null,req); 226 //return StringUtil.emptyIfNull(req.getContextPath())+StringUtil.emptyIfNull(req.getServletPath()); 227 if(key.equals(KeyConstants._server_name)) return toString(req.getServerName()); 228 if(key.equals(KeyConstants._server_protocol)) return toString(req.getProtocol()); 229 if(key.equals(KeyConstants._server_port)) return Caster.toString(req.getServerPort()); 230 if(key.equals(KeyConstants._server_port_secure))return req.isSecure()?"1":"0"; 231 232 } 233 else if(first=='p') { 234 if(key.equals(KeyConstants._path_info)) { 235 String pathInfo = Caster.toString(req.getAttribute("javax.servlet.include.path_info"),null); 236 if(StringUtil.isEmpty(pathInfo)) pathInfo = Caster.toString(req.getHeader("xajp-path-info"),null); 237 if(StringUtil.isEmpty(pathInfo)) pathInfo = req.getPathInfo(); 238 if(StringUtil.isEmpty(pathInfo)) { 239 pathInfo = Caster.toString(req.getAttribute("requestedPath"),null); 240 if(!StringUtil.isEmpty(pathInfo,true)) { 241 String scriptName = ReqRspUtil.getScriptName(null,req); 242 if ( pathInfo.startsWith(scriptName) ) 243 pathInfo = pathInfo.substring(scriptName.length()); 244 } 245 } 246 247 if(!StringUtil.isEmpty(pathInfo,true)) return pathInfo; 248 return ""; 249 } 250 if(key.equals(KeyConstants._path_translated)) return getPathTranslated(); 251 } 252 else if(first=='q') { 253 if(key.equals(KeyConstants._query_string))return doScriptProtect(toString(ReqRspUtil.getQueryString(req))); 254 } 255 } 256 257 // check header 258 String headerValue = (String) headers.get(key,null);//req.getHeader(key.getString()); 259 if(headerValue != null) return doScriptProtect(headerValue); 260 261 return other(key,defaultValue); 262 } 263 264 private Object getPathTranslated() { 265 try{ 266 PageContext pc = ThreadLocalPageContext.get(); 267 return pc.getBasePageSource().getResourceTranslated(pc).toString(); 268 } 269 catch(Throwable t){ 270 ExceptionUtil.rethrowIfNecessary(t); 271 } 272 return ""; 273 } 274 275 276 private Object other(Collection.Key key, Object defaultValue) { 277 if(staticKeys.containsKey(key)) return ""; 278 return defaultValue; 279 } 280 281 private String doScriptProtect(String value) { 282 if(isScriptProtected()) return ScriptProtect.translate(value); 283 return value; 284 } 285 286 private String toString(Object str) { 287 return StringUtil.toStringEmptyIfNull(str); 288 } 289 290 @Override 291 public Object get(Collection.Key key) { 292 Object value=get(key,""); 293 if(value==null)value= ""; 294 return value; 295 } 296 297 @Override 298 public Iterator<Collection.Key> keyIterator() { 299 return new KeyIterator(keys()); 300 } 301 302 @Override 303 public Iterator<String> keysAsStringIterator() { 304 return new StringIterator(keys()); 305 } 306 307 @Override 308 public Iterator<Entry<Key, Object>> entryIterator() { 309 return new EntryIterator(this, keys()); 310 } 311 312 @Override 313 public boolean isInitalized() { 314 return isInit; 315 } 316 317 @Override 318 public void initialize(PageContext pc) { 319 isInit=true; 320 req=pc.getHttpServletRequest(); 321 322 323 if(scriptProtected==ScriptProtected.UNDEFINED) { 324 scriptProtected=((pc.getApplicationContext().getScriptProtect()&ApplicationContext.SCRIPT_PROTECT_CGI)>0)? 325 ScriptProtected.YES:ScriptProtected.NO; 326 } 327 } 328 329 @Override 330 public void release() { 331 isInit=false; 332 scriptProtected=ScriptProtected.UNDEFINED; 333 req=null; 334 https=null; 335 headers=null; 336 337 } 338 339 @Override 340 public void release(PageContext pc) { 341 release(); 342 } 343 344 @Override 345 public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) { 346 return StructUtil.toDumpTable(this, "CGI Scope", pageContext, maxlevel, dp); 347 } 348 349 @Override 350 public int getType() { 351 return SCOPE_CGI; 352 } 353 354 @Override 355 public String getTypeAsString() { 356 return "cgi"; 357 } 358 359 public boolean isScriptProtected() { 360 return scriptProtected==ScriptProtected.YES; 361 } 362 363 @Override 364 public void setScriptProtecting(ApplicationContext ac,boolean scriptProtecting) { 365 scriptProtected=scriptProtecting?ScriptProtected.YES:ScriptProtected.NO; 366 } 367 368 369 public static String getDomain(HttpServletRequest req) { // DIFF 23 370 StringBuffer sb=new StringBuffer(); 371 sb.append(req.isSecure()?"https://":"http://"); 372 sb.append(req.getServerName()); 373 sb.append(':'); 374 sb.append(req.getServerPort()); 375 if(!StringUtil.isEmpty(req.getContextPath()))sb.append(req.getContextPath()); 376 return sb.toString(); 377 } 378 379}