// 更新session的列队 // @session // @mltSecond 需要重置的有效访问时间 // @return 更新成功返回true, false可能是找不到session或已经被设置最大有效时间为-1准备进行删除 func (sm *HttpSessionManager) updateSessionRank(session *httpSession, mltSecond int32) bool { sm.rwmutex.Lock() defer sm.rwmutex.Unlock() // 为了方便操作,session 与 sm.mapSessions[session.uid]获取的session是一致的 element, mapOk := sm.mapSessions[session.uid] if !mapOk { // 这里如果找不到的话,很有可能是被删除了,在高并发相同的请求下就很有可能进入这里。 // 出现这个问题基本是同一时间进行了很多个相同请求,然后又执行了自行执行销毁。 // 如果正常请求下很少会进入这里,因为会有个有效时间。然而如果自行进行了销毁,然后该请求又再次进入,不过表示该请求已经是无作为的了。 // 输入日志查看IP情况是否是恶意攻击。 if !sm.testing { thisLog.Error("%v: update session rank, mapSessions can not find key value. uuid = %v", session.accessIP.String(), session.uid) } return false } // 发现最大有效时间小于0的话,表示要删除了,所以返回false给用户重新创建。 if 0 >= session.maxlifeTime { return false } // 更换列队操作 if session.maxlifeTime != mltSecond { session.maxlifeTime = mltSecond element.Remove() // if origRankL, ok := sm.listRank[session.maxlifeTime]; ok { // origRankL.Remove(element) // } if rankList, ok := sm.listRank[mltSecond]; ok { // 这里如果出现相同请求的高并发可能会出现重复添加的情况。 // 不过相同请求的高并发一般是人为攻击照成的。不然高并发不同请求不会出现该问题。 sm.mapSessions[session.uid] = rankList.PushFront(session) } else { rankList = list.New() sm.mapSessions[session.uid] = rankList.PushFront(session) sm.listRank[mltSecond] = rankList } } else { element.MoveToFront() // if origRankL, ok := sm.listRank[session.maxlifeTime]; ok { // origRankL.MoveToFront(element) // } } session.accessTime = time.Now() return true }
// create session // @maxlifeTime // @request // @return func (sm *HttpSessionManager) createSession(maxlifeTime int32, request *http.Request) *httpSession { // 由于UUID里面有函数使用了全局的锁,所以需要放置这里 uuid, b64 := sm.getUUID() sm.rwmutex.Lock() defer sm.rwmutex.Unlock() s := &httpSession{} s.sessionManager = sm s.uid = b64 s.uidByte = []byte(uuid) s.maxlifeTime = maxlifeTime s.thisMap = make(map[string]interface{}) s.accessTime = time.Now() // 需要考虑存储IP的容量问题 s.ipRule = make(map[string]int) s.formToken = NewFormToken(FORM_TOKEN_SLICE_DEFAULT_LEN) // 设置IP if ip, b := sm.getUserIPAddr(request); b { s.accessIP = ip s.recordIPAccess(ip) } else { panic(thisLog.Error(ErrIPValidateFail + request.RemoteAddr)) } // 寻找@maxlifeTime的列队,如果寻找得到可以直接插入寻找到数列前面 rankList, ok := sm.listRank[maxlifeTime] if !ok { rankList = list.New() sm.listRank[maxlifeTime] = rankList } newElement := rankList.PushFront(s) sm.mapSessions[s.uid] = newElement if !sm.testing { thisLog.Info("%v: create session id:%v", s.accessIP.String(), s.uid) } sm.sessionCreateNum++ return s }