package org.fastcatsearch.http; import java.util.Map; import java.util.Map.Entry; import java.util.Timer; import java.util.TimerTask; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.fastcatsearch.http.action.ActionResponse; import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /* * single thread 동작. * */ public class HttpSessionManager { private static final Logger logger = LoggerFactory.getLogger(HttpSessionManager.class); public final static String DefaultSessionCookie = "JSESSIONID"; private Map<String, HttpSession> sessionObjMap; private int expireTimeInMiliseconds; private Timer timer; public HttpSessionManager() { this(1); } public HttpSessionManager(int expireTimeInHour) { sessionObjMap = new ConcurrentHashMap<String, HttpSession>(); timer = new Timer("HttpSessionManager-timer", true); timer.scheduleAtFixedRate(new SessionExpireTask(), 60 * 1000, 300 * 1000); ///5분에 한번 체크. setExpireTimeInHour(expireTimeInHour); } public HttpSession getSessionObj(String sessionId) { HttpSession sessionObj = sessionObjMap.get(sessionId); if (sessionObj == null) { sessionObj = new HttpSession(sessionId); sessionObjMap.put(sessionId, sessionObj); } return sessionObj; } public HttpSession handleCookie(HttpRequest request, ActionResponse actionResponse) { String cookieString = request.getHeader(HttpHeaders.Names.COOKIE); // logger.debug("cookie >> {}", cookieString); HttpSession sessionObj = null; String responseCookie = ""; boolean hasSessionCookie = false; if(cookieString != null){ String[] cookieArray = cookieString.split(";"); for (int i = 0; i < cookieArray.length; i++) { String cookie = cookieArray[i].trim(); String[] kv = cookie.split("="); String key = null; String value = null; if(kv.length > 0){ key = kv[0]; } if(kv.length > 1){ value = kv[1]; } if (DefaultSessionCookie.equalsIgnoreCase(key) && value != null && value.length() > 0) { // 세션쿠키 발견. hasSessionCookie = true; sessionObj = sessionObjMap.get(value); if (sessionObj == null) { sessionObj = new HttpSession(value); sessionObjMap.put(value, sessionObj); }else{ // logger.debug("세션객체 찾음. {} >> {}", kv[i], sessionObj.map()); } } else { if (responseCookie.length() > 0) { responseCookie += ";"; } responseCookie += cookie; } } } if (responseCookie.length() > 0) { actionResponse.setResponseCookie(responseCookie); } if (!hasSessionCookie) { // cookie가 없거나, 쿠키내에 JSESSIONID가 없다면 생성해서 Set-Cookie로 돌려준다.JSESSIONID=1bqe4dww377gy1c3pwqjzxbedj;Path=/admin //TODO expireTimeInHour를 날짜로 바꿔서 추가. ; Expires=Wed, 09 Jun 2021 10:18:14 GMT String newSessionId = newSessionId(); sessionObj = new HttpSession(newSessionId); sessionObjMap.put(newSessionId, sessionObj); logger.debug("New Session Created! {} >> {}", newSessionId, sessionObj); actionResponse.setResponseSetCookie(DefaultSessionCookie + "=" + newSessionId +";Path=/"); //경로구분없이 모두 동일한 session을 타도록 함. } if(sessionObj != null){ sessionObj.update(); } return sessionObj; } public void removeSession(String sessionId) { sessionObjMap.remove(sessionId); } private String newSessionId() { return UUID.randomUUID().toString(); } public void setExpireTimeInHour(int expireTimeInHour) { this.expireTimeInMiliseconds = expireTimeInHour * 3600 * 1000; } public void close(){ timer.cancel(); timer = null; sessionObjMap.clear(); sessionObjMap = null; } class SessionExpireTask extends TimerTask { @Override public void run() { long now = System.currentTimeMillis(); for(Entry<String, HttpSession> entry : sessionObjMap.entrySet()){ // logger.debug("entry > {}", entry.getValue()); if(now - entry.getValue().getLastTime() > expireTimeInMiliseconds){ sessionObjMap.remove(entry.getKey()); } } } } }