Skip to content

Commit

Permalink
support session
Browse files Browse the repository at this point in the history
  • Loading branch information
dworld committed Nov 8, 2014
1 parent c617d35 commit 72d8cb7
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 1 deletion.
2 changes: 1 addition & 1 deletion TODO
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
* change behaiver of default pipe handler OK
* context use ResponseWriter instead of http.ResponseWriter OK
* panic if write header after body OK
* add Session
* add Session OK
* add PipeHandler ErrorPage
* Example
38 changes: 38 additions & 0 deletions context_session.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package xingyun

var (
SessionKey string = "ZQSESSID"
sessionIDLen int = 36
)

func newSessionID() string {
return GenRandString(sessionIDLen)
}

func (ctx *Context) SetSession(key string, data []byte) {
ctx.Server.SessionStorage.SetSession(ctx.GetSessionID(), key, data)
}

func (ctx *Context) GetSession(key string) []byte {
return ctx.Server.SessionStorage.GetSession(ctx.GetSessionID(), key)
}

func (ctx *Context) ClearSession(key string) {
ctx.Server.SessionStorage.ClearSession(ctx.GetSessionID(), key)
}

func (ctx *Context) setNewSessionID() (sessionID string) {
sessionID = newSessionID()
ctx.SetCookie(SessionKey, sessionID)
return
}

// SetCookie adds a cookie header to the response.
func (ctx *Context) GetSessionID() (sessionID string) {
cookie, _ := ctx.Request.Cookie(SessionKey)

if cookie == nil || len(cookie.Value) != sessionIDLen {
return ctx.setNewSessionID()
}
return cookie.Value
}
2 changes: 2 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Server struct {
DefaultPipeHandlers []PipeHandler
PanicHandler ContextHandlerFunc
ErrorPageHandler ContextHandlerFunc
SessionStorage SessionStorage

pipes map[string]*Pipe
defaultPipe *Pipe
Expand All @@ -45,6 +46,7 @@ func NewServer(config *Config) *Server {

server.Router = newRouter(server.getURLVarLoaderPipeHandler())
server.StaticDir = http.Dir(config.StaticDir)
server.SessionStorage = NewMemoryStore()

server.SecureCookie = securecookie.New(
[]byte(config.CookieSecret),
Expand Down
26 changes: 26 additions & 0 deletions session_memory_store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package xingyun

// Simple session storage using memory, handy for development
// **NEVER** use it in production!!!
type memoryStore struct {
data map[string][]byte
}

func NewMemoryStore() *memoryStore {
return &memoryStore{
data: make(map[string][]byte),
}
}

func (ms *memoryStore) SetSession(sessionID string, key string, data []byte) {
ms.data[sessionID+key] = data
}

func (ms *memoryStore) GetSession(sessionID string, key string) []byte {
data, _ := ms.data[sessionID+key]
return data
}

func (ms *memoryStore) ClearSession(sessionID string, key string) {
delete(ms.data, sessionID+key)
}
49 changes: 49 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package xingyun

//This code is adapted from https://github.com/dustin/randbo

import (
"fmt"
"io"
"math/rand"
"time"
)

// Randbo creates a stream of non-crypto quality random bytes
type randbo struct {
rand.Source
}

// New creates a new random reader with a time source.
func newRandbo() io.Reader {
return newRandoFrom(rand.NewSource(time.Now().UnixNano()))
}

// NewFrom creates a new reader from your own rand.Source
func newRandoFrom(src rand.Source) io.Reader {
return &randbo{src}
}

// Read satisfies io.Reader
func (r *randbo) Read(p []byte) (n int, err error) {
todo := len(p)
offset := 0
for {
val := int64(r.Int63())
for i := 0; i < 8; i++ {
p[offset] = byte(val)
todo--
if todo == 0 {
return len(p), nil
}
offset++
val >>= 8
}
}
}

func GenRandString(length int) string {
buf := make([]byte, length)
newRandbo().Read(buf)
return fmt.Sprintf("%x", buf)
}

0 comments on commit 72d8cb7

Please sign in to comment.