Base64 URLEncoding could generate "-", So it's not safe to use "--" as sign separator. I encounter this tricky bug quite frequently #21

Merged
merged 2 commits into from Mar 26, 2012
View
28 sessions.go
@@ -2,13 +2,13 @@ package mango
import (
"bytes"
- "hash"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
+ "encoding/gob"
"fmt"
+ "hash"
"io/ioutil"
- "encoding/gob"
"net/http"
"strings"
)
@@ -50,7 +50,7 @@ func decode64(value string) (result string) {
func decodeCookie(value, secret string) (cookie map[string]interface{}) {
cookie = make(map[string]interface{})
- split := strings.Split(string(value), "--")
+ split := strings.Split(string(value), "/")
if len(split) < 2 {
return cookie
@@ -91,7 +91,7 @@ func encode64(value string) (result string) {
func encodeCookie(value map[string]interface{}, secret string) (cookie string) {
data := encodeGob(value)
- return fmt.Sprintf("%s--%s", encode64(data), encode64(hashCookie(data, secret)))
+ return fmt.Sprintf("%s/%s", encode64(data), encode64(hashCookie(data, secret)))
}
func prepareSession(env Env, key, secret string) {
@@ -106,19 +106,31 @@ func prepareSession(env Env, key, secret string) {
env["mango.session"] = make(map[string]interface{})
}
-func commitSession(headers Headers, env Env, key, secret, domain string) {
+func commitSession(headers Headers, env Env, key, secret string, options *CookieOptions) {
cookie := new(http.Cookie)
cookie.Name = key
cookie.Value = encodeCookie(env["mango.session"].(map[string]interface{}), secret)
- cookie.Domain = domain
+ cookie.Path = options.Path
+ cookie.Domain = options.Domain
+ cookie.MaxAge = options.MaxAge
+ cookie.Secure = options.Secure
+ cookie.HttpOnly = options.HttpOnly
headers.Add("Set-Cookie", cookie.String())
}
-func Sessions(secret, key, domain string) Middleware {
+type CookieOptions struct {
+ Domain string
+ Path string
+ MaxAge int
+ Secure bool
+ HttpOnly bool
+}
+
+func Sessions(secret, key string, options *CookieOptions) Middleware {
return func(env Env, app App) (status Status, headers Headers, body Body) {
prepareSession(env, key, secret)
status, headers, body = app(env)
- commitSession(headers, env, key, secret, domain)
+ commitSession(headers, env, key, secret, options)
return status, headers, body
}
}
View
4 sessions_test.go
@@ -32,7 +32,7 @@ func TestSessions(t *testing.T) {
// Compile the stack
sessionsStack := new(Stack)
- sessionsStack.Middleware(Sessions("my_secret", "my_key", ".my.domain.com"))
+ sessionsStack.Middleware(Sessions("my_secret", "my_key", &CookieOptions{Domain: ".my.domain.com"}))
sessionsApp := sessionsStack.Compile(sessionsTestServer)
// Request against it
@@ -83,7 +83,7 @@ func BenchmarkSessions(b *testing.B) {
}
sessionsStack := new(Stack)
- sessionsStack.Middleware(Sessions("my_secret", "my_key", ".my.domain.com"))
+ sessionsStack.Middleware(Sessions("my_secret", "my_key", &CookieOptions{Domain: ".my.domain.com"}))
sessionsApp := sessionsStack.Compile(sessionsTestServer)
request, _ := http.NewRequest("GET", "http://localhost:3000/", nil)