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.util.ArrayList; 022import java.util.Enumeration; 023import java.util.HashSet; 024import java.util.Iterator; 025import java.util.List; 026import java.util.Set; 027 028import javax.servlet.http.HttpSession; 029import javax.servlet.http.HttpSessionBindingEvent; 030import javax.servlet.http.HttpSessionBindingListener; 031 032import lucee.commons.lang.ExceptionUtil; 033import lucee.runtime.PageContext; 034import lucee.runtime.engine.ThreadLocalPageContext; 035import lucee.runtime.listener.ApplicationContext; 036import lucee.runtime.type.Collection; 037import lucee.runtime.type.scope.storage.MemoryScope; 038import lucee.runtime.type.util.KeyConstants; 039 040/** 041 * 042 */ 043public final class JSession extends ScopeSupport implements Session,HttpSessionBindingListener,MemoryScope { 044 045 public static final Collection.Key SESSION_ID = KeyConstants._sessionid; 046 private static Set<Collection.Key> FIX_KEYS=new HashSet<Collection.Key>(); 047 static { 048 FIX_KEYS.add(KeyConstants._sessionid); 049 FIX_KEYS.add(KeyConstants._urltoken); 050 } 051 052 053 private String name; 054 private long timespan=-1; 055 private transient HttpSession httpSession; 056 private long lastAccess; 057 private long created; 058 059 /** 060 * constructor of the class 061 */ 062 public JSession() { 063 super(true,"session",SCOPE_SESSION); 064 setDisplayName("Scope Session (Type JEE)"); 065 this.created=System.currentTimeMillis(); 066 } 067 068 @Override 069 public void touchBeforeRequest(PageContext pc) { 070 071 ApplicationContext appContext = pc.getApplicationContext(); 072 timespan=appContext.getSessionTimeout().getMillis(); 073 this.name=appContext.getName(); 074 HttpSession hs = pc.getSession(); 075 String id=""; 076 try{ 077 if(hs!=null)this.httpSession=hs; 078 if(httpSession!=null) { 079 id = httpSession.getId(); 080 int timeoutInSeconds = ((int)(timespan/1000))+60; 081 if(httpSession.getMaxInactiveInterval()<timeoutInSeconds) 082 httpSession.setMaxInactiveInterval(timeoutInSeconds); 083 } 084 085 } 086 catch(Throwable t) { 087 ExceptionUtil.rethrowIfNecessary(t); 088 089 } 090 091 092 lastAccess=System.currentTimeMillis(); 093 setEL(KeyConstants._sessionid,id); 094 setEL(KeyConstants._urltoken,"CFID="+pc.getCFID()+"&CFTOKEN="+pc.getCFToken()+"&jsessionid="+id); 095 } 096 097 public void touchAfterRequest(PageContext pc) { 098 099 } 100 @Override 101 public void release() { 102 release(ThreadLocalPageContext.get()); 103 } 104 105 @Override 106 public void release(PageContext pc) { 107 if(httpSession!=null){ 108 try { 109 Object key; 110 Enumeration e = httpSession.getAttributeNames(); 111 while(e.hasMoreElements()) { 112 // TODO set inative time new 113 key=e.nextElement(); 114 if(key.equals(name))httpSession.removeAttribute(name); 115 } 116 name=null; 117 timespan=-1; 118 httpSession=null; 119 lastAccess=-1; 120 } 121 catch(Throwable t) { 122 ExceptionUtil.rethrowIfNecessary(t); 123 } 124 } 125 super.release(pc); 126 } 127 128 @Override 129 public long getLastAccess() { 130 return lastAccess; 131 } 132 133 @Override 134 public long getTimeSpan() { 135 return timespan; 136 } 137 138 @Override 139 public boolean isExpired() { 140 return (getLastAccess()+getTimeSpan())<System.currentTimeMillis(); 141 } 142 143 @Override 144 public void valueBound(HttpSessionBindingEvent event) { 145 146 } 147 148 @Override 149 public void valueUnbound(HttpSessionBindingEvent event) { 150 clear(); 151 } 152 153 @Override 154 public void touch() { 155 lastAccess=System.currentTimeMillis(); 156 } 157 158 @Override 159 public long getCreated() { 160 return created; 161 } 162 163 public Collection.Key[] pureKeys() { 164 List<Collection.Key> keys=new ArrayList<Collection.Key>(); 165 Iterator<Key> it = keyIterator(); 166 Collection.Key key; 167 while(it.hasNext()){ 168 key=it.next(); 169 if(!FIX_KEYS.contains(key))keys.add(key); 170 } 171 return keys.toArray(new Collection.Key[keys.size()]); 172 } 173 174 @Override 175 public void resetEnv(PageContext pc) { 176 created=System.currentTimeMillis(); 177 lastAccess=System.currentTimeMillis(); 178 touchBeforeRequest(pc); 179 } 180}