mirror of
https://github.com/kataras/iris.git
synced 2026-01-06 11:37:06 +00:00
This commit is contained in:
@@ -2,7 +2,7 @@ package sessions
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -23,9 +23,10 @@ type (
|
||||
// Manager implements the IManager interface
|
||||
// contains the cookie's name, the provider and a duration for GC and cookie life expire
|
||||
Manager struct {
|
||||
config *config.Sessions
|
||||
provider IProvider
|
||||
mu sync.Mutex
|
||||
config *config.Sessions
|
||||
provider IProvider
|
||||
mu sync.Mutex
|
||||
compiledCookie string
|
||||
}
|
||||
)
|
||||
|
||||
@@ -46,7 +47,7 @@ func newManager(c config.Sessions) (*Manager, error) {
|
||||
manager := &Manager{}
|
||||
manager.config = &c
|
||||
manager.provider = provider
|
||||
|
||||
manager.compiledCookie = base64.URLEncoding.EncodeToString([]byte(c.Cookie))
|
||||
return manager, nil
|
||||
}
|
||||
|
||||
@@ -74,29 +75,57 @@ func (m *Manager) generateSessionID() string {
|
||||
return base64.URLEncoding.EncodeToString(utils.Random(32))
|
||||
}
|
||||
|
||||
var dotB = byte('.')
|
||||
|
||||
// Start starts the session
|
||||
func (m *Manager) Start(ctx context.IContext) store.IStore {
|
||||
|
||||
m.mu.Lock()
|
||||
var store store.IStore
|
||||
requestCtx := ctx.GetRequestCtx()
|
||||
cookieValue := string(requestCtx.Request.Header.Cookie(m.config.Cookie))
|
||||
cookieValue := string(requestCtx.Request.Header.Cookie(m.compiledCookie))
|
||||
|
||||
if cookieValue == "" { // cookie doesn't exists, let's generate a session and add set a cookie
|
||||
sid := m.generateSessionID()
|
||||
store, _ = m.provider.Init(sid)
|
||||
cookie := fasthttp.AcquireCookie()
|
||||
cookie.SetKey(m.config.Cookie)
|
||||
cookie.SetValue(url.QueryEscape(sid))
|
||||
// The RFC makes no mention of encoding url value, so here I think to encode both sessionid key and the value using the safe(to put and to use as cookie) url-encoding
|
||||
cookie.SetKey(m.compiledCookie)
|
||||
cookie.SetValue(base64.URLEncoding.EncodeToString([]byte(sid)))
|
||||
cookie.SetPath("/")
|
||||
if !m.config.DisableSubdomainPersistance {
|
||||
requestDomain := ctx.HostString() // we don't use the ctx.Domain because it gives the virtual domain, which is correct on some cases but not here.
|
||||
|
||||
if portIdx := strings.IndexByte(requestDomain, ':'); portIdx > 0 {
|
||||
requestDomain = requestDomain[0:portIdx]
|
||||
}
|
||||
// RFC2109, we allow level 1 subdomains, but no further
|
||||
// if we have localhost.com , we want the localhost.com.
|
||||
// so if we have something like: mysubdomain.localhost.com we want the localhost here
|
||||
// if we have mysubsubdomain.mysubdomain.localhost.com we want the .mysubdomain.localhost.com here
|
||||
// slow things here, especially the 'replace' but this is a good and understable( I hope) way to get the be able to set cookies from subdomains & domain with 1-level limit
|
||||
if dotIdx := strings.LastIndexByte(requestDomain, dotB); dotIdx > 0 {
|
||||
// is mysubdomain.localhost.com || mysubsubdomain.mysubdomain.localhost.com
|
||||
s := requestDomain[0:dotIdx] // set mysubdomain.localhost || mysubsubdomain.mysubdomain.localhost
|
||||
if secondDotIdx := strings.LastIndexByte(s, dotB); secondDotIdx > 0 {
|
||||
//is mysubdomain.localhost || mysubsubdomain.mysubdomain.localhost
|
||||
s = s[secondDotIdx+1:] // set to localhost || mysubdomain.localhost
|
||||
}
|
||||
// replace the s with the requestDomain before the domain's siffux
|
||||
subdomainSuff := strings.LastIndexByte(requestDomain, dotB)
|
||||
if subdomainSuff > len(s) { // if it is actual exists as subdomain suffix
|
||||
requestDomain = strings.Replace(requestDomain, requestDomain[0:subdomainSuff], s, 1) // set to localhost.com || mysubdomain.localhost.com
|
||||
}
|
||||
}
|
||||
cookie.SetDomain("." + requestDomain) // . to allow persistance
|
||||
}
|
||||
cookie.SetHTTPOnly(true)
|
||||
cookie.SetExpire(m.config.Expires)
|
||||
requestCtx.Response.Header.SetCookie(cookie)
|
||||
fasthttp.ReleaseCookie(cookie)
|
||||
//println("manager.go:156-> Setting cookie with lifetime: ", m.lifeDuration.Seconds())
|
||||
} else {
|
||||
sid, _ := url.QueryUnescape(cookieValue)
|
||||
store, _ = m.provider.Read(sid)
|
||||
sid, _ := base64.URLEncoding.DecodeString(cookieValue)
|
||||
store, _ = m.provider.Read(string(sid))
|
||||
}
|
||||
|
||||
m.mu.Unlock()
|
||||
|
||||
Reference in New Issue
Block a user