sess_mem.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // Copyright 2014 beego Author. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package session
  15. import (
  16. "container/list"
  17. "net/http"
  18. "sync"
  19. "time"
  20. )
  21. var mempder = &MemProvider{list: list.New(), sessions: make(map[string]*list.Element)}
  22. // MemSessionStore memory session store.
  23. // it saved sessions in a map in memory.
  24. type MemSessionStore struct {
  25. sid string //session id
  26. timeAccessed time.Time //last access time
  27. value map[interface{}]interface{} //session store
  28. lock sync.RWMutex
  29. }
  30. // Set value to memory session
  31. func (st *MemSessionStore) Set(key, value interface{}) error {
  32. st.lock.Lock()
  33. defer st.lock.Unlock()
  34. st.value[key] = value
  35. return nil
  36. }
  37. // Get value from memory session by key
  38. func (st *MemSessionStore) Get(key interface{}) interface{} {
  39. st.lock.RLock()
  40. defer st.lock.RUnlock()
  41. if v, ok := st.value[key]; ok {
  42. return v
  43. }
  44. return nil
  45. }
  46. // Delete in memory session by key
  47. func (st *MemSessionStore) Delete(key interface{}) error {
  48. st.lock.Lock()
  49. defer st.lock.Unlock()
  50. delete(st.value, key)
  51. return nil
  52. }
  53. // Flush clear all values in memory session
  54. func (st *MemSessionStore) Flush() error {
  55. st.lock.Lock()
  56. defer st.lock.Unlock()
  57. st.value = make(map[interface{}]interface{})
  58. return nil
  59. }
  60. // SessionID get this id of memory session store
  61. func (st *MemSessionStore) SessionID() string {
  62. return st.sid
  63. }
  64. // SessionRelease Implement method, no used.
  65. func (st *MemSessionStore) SessionRelease(w http.ResponseWriter) {
  66. }
  67. // MemProvider Implement the provider interface
  68. type MemProvider struct {
  69. lock sync.RWMutex // locker
  70. sessions map[string]*list.Element // map in memory
  71. list *list.List // for gc
  72. maxlifetime int64
  73. savePath string
  74. }
  75. // SessionInit init memory session
  76. func (pder *MemProvider) SessionInit(maxlifetime int64, savePath string) error {
  77. pder.maxlifetime = maxlifetime
  78. pder.savePath = savePath
  79. return nil
  80. }
  81. // SessionRead get memory session store by sid
  82. func (pder *MemProvider) SessionRead(sid string) (Store, error) {
  83. pder.lock.RLock()
  84. if element, ok := pder.sessions[sid]; ok {
  85. go pder.SessionUpdate(sid)
  86. pder.lock.RUnlock()
  87. return element.Value.(*MemSessionStore), nil
  88. }
  89. pder.lock.RUnlock()
  90. pder.lock.Lock()
  91. newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})}
  92. element := pder.list.PushFront(newsess)
  93. pder.sessions[sid] = element
  94. pder.lock.Unlock()
  95. return newsess, nil
  96. }
  97. // SessionExist check session store exist in memory session by sid
  98. func (pder *MemProvider) SessionExist(sid string) bool {
  99. pder.lock.RLock()
  100. defer pder.lock.RUnlock()
  101. if _, ok := pder.sessions[sid]; ok {
  102. return true
  103. }
  104. return false
  105. }
  106. // SessionRegenerate generate new sid for session store in memory session
  107. func (pder *MemProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
  108. pder.lock.RLock()
  109. if element, ok := pder.sessions[oldsid]; ok {
  110. go pder.SessionUpdate(oldsid)
  111. pder.lock.RUnlock()
  112. pder.lock.Lock()
  113. element.Value.(*MemSessionStore).sid = sid
  114. pder.sessions[sid] = element
  115. delete(pder.sessions, oldsid)
  116. pder.lock.Unlock()
  117. return element.Value.(*MemSessionStore), nil
  118. }
  119. pder.lock.RUnlock()
  120. pder.lock.Lock()
  121. newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})}
  122. element := pder.list.PushFront(newsess)
  123. pder.sessions[sid] = element
  124. pder.lock.Unlock()
  125. return newsess, nil
  126. }
  127. // SessionDestroy delete session store in memory session by id
  128. func (pder *MemProvider) SessionDestroy(sid string) error {
  129. pder.lock.Lock()
  130. defer pder.lock.Unlock()
  131. if element, ok := pder.sessions[sid]; ok {
  132. delete(pder.sessions, sid)
  133. pder.list.Remove(element)
  134. return nil
  135. }
  136. return nil
  137. }
  138. // SessionGC clean expired session stores in memory session
  139. func (pder *MemProvider) SessionGC() {
  140. pder.lock.RLock()
  141. for {
  142. element := pder.list.Back()
  143. if element == nil {
  144. break
  145. }
  146. if (element.Value.(*MemSessionStore).timeAccessed.Unix() + pder.maxlifetime) < time.Now().Unix() {
  147. pder.lock.RUnlock()
  148. pder.lock.Lock()
  149. pder.list.Remove(element)
  150. delete(pder.sessions, element.Value.(*MemSessionStore).sid)
  151. pder.lock.Unlock()
  152. pder.lock.RLock()
  153. } else {
  154. break
  155. }
  156. }
  157. pder.lock.RUnlock()
  158. }
  159. // SessionAll get count number of memory session
  160. func (pder *MemProvider) SessionAll() int {
  161. return pder.list.Len()
  162. }
  163. // SessionUpdate expand time of session store by id in memory session
  164. func (pder *MemProvider) SessionUpdate(sid string) error {
  165. pder.lock.Lock()
  166. defer pder.lock.Unlock()
  167. if element, ok := pder.sessions[sid]; ok {
  168. element.Value.(*MemSessionStore).timeAccessed = time.Now()
  169. pder.list.MoveToFront(element)
  170. return nil
  171. }
  172. return nil
  173. }
  174. func init() {
  175. Register("memory", mempder)
  176. }