func (s *Session) Put(r *http.Request, key string, val interface{}) {
	c := getCacheFromRequestContext(r)
	c.mu.Lock()
	c.Data[key] = val
	c.modified = true
	c.mu.Unlock()
}
Put adds a key and corresponding value to the session data. Any existing
value for the key will be replaced.
package sessions
import (
	"bytes"
	"context"
	"encoding/gob"
	"errors"
	"net/http"
	"sort"
	"sync"
	"time"
)
type contextKey string
var contextKeyCache = contextKey("cache")
var errMissingCache = errors.New("session: cache not present in request context")
type cache struct {
	Data      map[string]interface{}
	Expiry    time.Time
	modified  bool
	destroyed bool
	mu        sync.Mutex
}
func newCache(lifetime time.Duration) *cache {
	return &cache{
		Data:   make(map[string]interface{}),
		Expiry: time.Now().Add(lifetime).UTC(),
	}
}
func (c *cache) encode(key [32]byte) (string, error) {
	var b bytes.Buffer
	err := gob.NewEncoder(&b).Encode(c)
	if err != nil {
		return "", err
	}
	return encrypt(b.Bytes(), key)
}
func (c *cache) decode(token string, keys [][32]byte) error {
	b, err := decrypt(token, keys)
	if err != nil {
		return err
	}
	r := bytes.NewReader(b)
	return gob.NewDecoder(r).Decode(c)
}
func addCacheToRequestContext(r *http.Request, c *cache) *http.Request {
	ctx := context.WithValue(r.Context(), contextKeyCache, c)
	return r.WithContext(ctx)
}
func getCacheFromRequestContext(r *http.Request) *cache {
	c, ok := r.Context().Value(contextKeyCache).(*cache)
	if !ok {
		panic(errMissingCache)
	}
	return c
}