sess_couchbase.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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 couchbase for session provider
  15. //
  16. // depend on github.com/couchbaselabs/go-couchbasee
  17. //
  18. // go install github.com/couchbaselabs/go-couchbase
  19. //
  20. // Usage:
  21. // import(
  22. // _ "github.com/astaxie/beego/session/couchbase"
  23. // "github.com/astaxie/beego/session"
  24. // )
  25. //
  26. // func init() {
  27. // globalSessions, _ = session.NewManager("couchbase", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"http://host:port/, Pool, Bucket"}``)
  28. // go globalSessions.GC()
  29. // }
  30. //
  31. // more docs: http://beego.me/docs/module/session.md
  32. package couchbase
  33. import (
  34. "net/http"
  35. "strings"
  36. "sync"
  37. couchbase "github.com/couchbase/go-couchbase"
  38. "github.com/astaxie/beego/session"
  39. )
  40. var couchbpder = &Provider{}
  41. // SessionStore store each session
  42. type SessionStore struct {
  43. b *couchbase.Bucket
  44. sid string
  45. lock sync.RWMutex
  46. values map[interface{}]interface{}
  47. maxlifetime int64
  48. }
  49. // Provider couchabse provided
  50. type Provider struct {
  51. maxlifetime int64
  52. savePath string
  53. pool string
  54. bucket string
  55. b *couchbase.Bucket
  56. }
  57. // Set value to couchabse session
  58. func (cs *SessionStore) Set(key, value interface{}) error {
  59. cs.lock.Lock()
  60. defer cs.lock.Unlock()
  61. cs.values[key] = value
  62. return nil
  63. }
  64. // Get value from couchabse session
  65. func (cs *SessionStore) Get(key interface{}) interface{} {
  66. cs.lock.RLock()
  67. defer cs.lock.RUnlock()
  68. if v, ok := cs.values[key]; ok {
  69. return v
  70. }
  71. return nil
  72. }
  73. // Delete value in couchbase session by given key
  74. func (cs *SessionStore) Delete(key interface{}) error {
  75. cs.lock.Lock()
  76. defer cs.lock.Unlock()
  77. delete(cs.values, key)
  78. return nil
  79. }
  80. // Flush Clean all values in couchbase session
  81. func (cs *SessionStore) Flush() error {
  82. cs.lock.Lock()
  83. defer cs.lock.Unlock()
  84. cs.values = make(map[interface{}]interface{})
  85. return nil
  86. }
  87. // SessionID Get couchbase session store id
  88. func (cs *SessionStore) SessionID() string {
  89. return cs.sid
  90. }
  91. // SessionRelease Write couchbase session with Gob string
  92. func (cs *SessionStore) SessionRelease(w http.ResponseWriter) {
  93. defer cs.b.Close()
  94. bo, err := session.EncodeGob(cs.values)
  95. if err != nil {
  96. return
  97. }
  98. cs.b.Set(cs.sid, int(cs.maxlifetime), bo)
  99. }
  100. func (cp *Provider) getBucket() *couchbase.Bucket {
  101. c, err := couchbase.Connect(cp.savePath)
  102. if err != nil {
  103. return nil
  104. }
  105. pool, err := c.GetPool(cp.pool)
  106. if err != nil {
  107. return nil
  108. }
  109. bucket, err := pool.GetBucket(cp.bucket)
  110. if err != nil {
  111. return nil
  112. }
  113. return bucket
  114. }
  115. // SessionInit init couchbase session
  116. // savepath like couchbase server REST/JSON URL
  117. // e.g. http://host:port/, Pool, Bucket
  118. func (cp *Provider) SessionInit(maxlifetime int64, savePath string) error {
  119. cp.maxlifetime = maxlifetime
  120. configs := strings.Split(savePath, ",")
  121. if len(configs) > 0 {
  122. cp.savePath = configs[0]
  123. }
  124. if len(configs) > 1 {
  125. cp.pool = configs[1]
  126. }
  127. if len(configs) > 2 {
  128. cp.bucket = configs[2]
  129. }
  130. return nil
  131. }
  132. // SessionRead read couchbase session by sid
  133. func (cp *Provider) SessionRead(sid string) (session.Store, error) {
  134. cp.b = cp.getBucket()
  135. var doc []byte
  136. err := cp.b.Get(sid, &doc)
  137. var kv map[interface{}]interface{}
  138. if doc == nil {
  139. kv = make(map[interface{}]interface{})
  140. } else {
  141. kv, err = session.DecodeGob(doc)
  142. if err != nil {
  143. return nil, err
  144. }
  145. }
  146. cs := &SessionStore{b: cp.b, sid: sid, values: kv, maxlifetime: cp.maxlifetime}
  147. return cs, nil
  148. }
  149. // SessionExist Check couchbase session exist.
  150. // it checkes sid exist or not.
  151. func (cp *Provider) SessionExist(sid string) bool {
  152. cp.b = cp.getBucket()
  153. defer cp.b.Close()
  154. var doc []byte
  155. if err := cp.b.Get(sid, &doc); err != nil || doc == nil {
  156. return false
  157. }
  158. return true
  159. }
  160. // SessionRegenerate remove oldsid and use sid to generate new session
  161. func (cp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
  162. cp.b = cp.getBucket()
  163. var doc []byte
  164. if err := cp.b.Get(oldsid, &doc); err != nil || doc == nil {
  165. cp.b.Set(sid, int(cp.maxlifetime), "")
  166. } else {
  167. err := cp.b.Delete(oldsid)
  168. if err != nil {
  169. return nil, err
  170. }
  171. _, _ = cp.b.Add(sid, int(cp.maxlifetime), doc)
  172. }
  173. err := cp.b.Get(sid, &doc)
  174. if err != nil {
  175. return nil, err
  176. }
  177. var kv map[interface{}]interface{}
  178. if doc == nil {
  179. kv = make(map[interface{}]interface{})
  180. } else {
  181. kv, err = session.DecodeGob(doc)
  182. if err != nil {
  183. return nil, err
  184. }
  185. }
  186. cs := &SessionStore{b: cp.b, sid: sid, values: kv, maxlifetime: cp.maxlifetime}
  187. return cs, nil
  188. }
  189. // SessionDestroy Remove bucket in this couchbase
  190. func (cp *Provider) SessionDestroy(sid string) error {
  191. cp.b = cp.getBucket()
  192. defer cp.b.Close()
  193. cp.b.Delete(sid)
  194. return nil
  195. }
  196. // SessionGC Recycle
  197. func (cp *Provider) SessionGC() {
  198. return
  199. }
  200. // SessionAll return all active session
  201. func (cp *Provider) SessionAll() int {
  202. return 0
  203. }
  204. func init() {
  205. session.Register("couchbase", couchbpder)
  206. }