From 781abb00eaa85f309245317cbca179e70a4d8b88 Mon Sep 17 00:00:00 2001 From: Makis Maropoulos Date: Thu, 30 Jun 2016 14:26:42 +0300 Subject: [PATCH] Fix https://github.com/kataras/iris/issues/244 and some more things --- context.go | 11 ++------ sessions/manager.go | 61 ++++++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/context.go b/context.go index 0a13250e..823ebc7e 100644 --- a/context.go +++ b/context.go @@ -713,15 +713,8 @@ func (ctx *Context) SetCookieKV(key, value string) { // RemoveCookie deletes a cookie by it's name/key func (ctx *Context) RemoveCookie(name string) { - cookie := fasthttp.AcquireCookie() - cookie.SetKey(name) - cookie.SetValue("") - cookie.SetPath("/") - cookie.SetHTTPOnly(true) - exp := time.Now().Add(-time.Duration(1) * time.Minute) //RFC says 1 second, but make sure 1 minute because we are using fasthttp - cookie.SetExpire(exp) - ctx.Response.Header.SetCookie(cookie) - fasthttp.ReleaseCookie(cookie) + ctx.RequestCtx.Request.Header.DelCookie(name) + ctx.RequestCtx.Response.Header.DelClientCookie(name) } // GetFlash get a flash message by it's key diff --git a/sessions/manager.go b/sessions/manager.go index e509a374..27358d32 100644 --- a/sessions/manager.go +++ b/sessions/manager.go @@ -23,10 +23,9 @@ 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 - compiledCookie string + config *config.Sessions + provider IProvider + mu sync.Mutex } ) @@ -47,7 +46,7 @@ func newManager(c config.Sessions) (*Manager, error) { manager := &Manager{} manager.config = &c manager.provider = provider - manager.compiledCookie = base64.URLEncoding.EncodeToString([]byte(c.Cookie)) + manager.config.Cookie = base64.URLEncoding.EncodeToString([]byte(c.Cookie)) // change the cookie's name/key to a more safe return manager, nil } @@ -83,41 +82,45 @@ 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.compiledCookie)) + cookieValue := string(requestCtx.Request.Header.Cookie(m.config.Cookie)) 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() // 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.SetKey(m.config.Cookie) cookie.SetValue(base64.URLEncoding.EncodeToString([]byte(sid))) cookie.SetPath("/") if !m.config.DisableSubdomainPersistance { requestDomain := ctx.HostString() + // there is a problem with .localhost setted as the domain, so we check that first + if strings.Count(requestDomain, ".") > 0 { + 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 + } + } + // finally set the .localhost.com (for(1-level) || .mysubdomain.localhost.com (for 2-level subdomain allow) + cookie.SetDomain("." + requestDomain) // . to allow persistance + } - 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)