<commit_before>package sessionmw

import (
	"errors"
	"fmt"
	"math/rand"
	"net/http"
	"sync"
	"time"

	"github.com/gorilla/securecookie"
	"github.com/knq/baseconv"

	"goji.io"

	"golang.org/x/net/context"
)

// context store constants
type contextKey int

// the various keys stored in context.Context
const (
	sessionContextKey    contextKey = 0
	sessionIDContextKey  contextKey = 1
	storeContextKey      contextKey = 2
	cookieNameContextKey contextKey = 3
)

const (
	// DefaultCookieName is the default cookie name
	DefaultCookieName = "SESSID"
)

// IDFn is the ID generation func type.
type IDFn func() string

// session is the session storage.
type session struct {
	sync.RWMutex
	data map[string]interface{}
}

// ID retrieves the id for this session.
func ID(ctxt context.Context) string {
	sessID := ctxt.Value(sessionIDContextKey).(string)
	return sessID
}

// Set stores a session value into the context.
func Set(ctxt context.Context, key string, val interface{}) {
	sess := ctxt.Value(sessionContextKey).(session)
	sess.Lock()
	sess.data[key] = val
	sess.Unlock()
}

// Get retrieves a session value from the context.
func Get(ctxt context.Context, key string) (interface{}, bool) {
	sess := ctxt.Value(sessionContextKey).(session)
	sess.RLock()
	val, ok := sess.data[key]
	sess.RUnlock()
	return val, ok
}

// Delete removes a session value from the context.
func Delete(ctxt context.Context, key string) {
	sess := ctxt.Value(sessionContextKey).(session)
	sess.Lock()
	delete(sess.data, key)
	sess.Unlock()
}

// GetStore retrieves the session store from the context.
func GetStore(ctxt context.Context) Store {
	st := ctxt.Value(storeContextKey).(Store)
	return st
}

// CookieName retrieves the cookie name from the context.
func CookieName(ctxt context.Context) string {
	return ctxt.Value(cookieNameContextKey).(string)
}

// Destroy destroys a session.
//
// Note that any existing values will continue to remain in the context after
// destruction. The context should be closed (or destroyed).
//
// If the optional http.ResponseWriter is provided, then an expired cookie will
// be added to the response headers.
func Destroy(ctxt context.Context, res ...http.ResponseWriter) error {
	sessID := ID(ctxt)
	st := GetStore(ctxt)

	if len(res) > 0 {
		http.SetCookie(res[0], &http.Cookie{
			Name:    CookieName(ctxt),
			Expires: time.Now(),
			Value:   "-",
			MaxAge:  -1,
		})
	}

	return st.Destroy(sessID)
}

// Config contains the configuration parameters for the session middleware.
type Config struct {
	Secret      string
	BlockSecret string

	Store Store
	IDFn  IDFn

	Name     string
	Path     string
	Domain   string
	Expires  time.Time
	MaxAge   time.Duration
	Secure   bool
	HttpOnly bool
}

// Handler provides the goji.Handler for the session middleware.
func (c Config) Handler(h goji.Handler) goji.Handler {<commit_msg>Updating documentation in sessionmw.go<commit_after>// Package sessionmw provides a Goji v2 context aware session middleware.
package sessionmw

import (
	"errors"
	"fmt"
	"math/rand"
	"net/http"
	"sync"
	"time"

	"github.com/gorilla/securecookie"
	"github.com/knq/baseconv"

	"goji.io"

	"golang.org/x/net/context"
)

// context store constants
type contextKey int

// the various keys stored in context.Context
const (
	sessionContextKey    contextKey = 0
	sessionIDContextKey  contextKey = 1
	storeContextKey      contextKey = 2
	cookieNameContextKey contextKey = 3
)

const (
	// DefaultCookieName is the default cookie name.
	DefaultCookieName = "SESSID"
)

// IDFn is the ID generation func type.
type IDFn func() string

// session is the session storage.
type session struct {
	sync.RWMutex
	data map[string]interface{}
}

// ID retrieves the id for this session from the context.
func ID(ctxt context.Context) string {
	sessID := ctxt.Value(sessionIDContextKey).(string)
	return sessID
}

// Set stores a session value into the context.
//
// Session values will be saved to the underlying store after Handler has
// finished.
func Set(ctxt context.Context, key string, val interface{}) {
	sess := ctxt.Value(sessionContextKey).(session)
	sess.Lock()
	sess.data[key] = val
	sess.Unlock()
}

// Get retrieves a previously stored session value from the context.
func Get(ctxt context.Context, key string) (interface{}, bool) {
	sess := ctxt.Value(sessionContextKey).(session)
	sess.RLock()
	val, ok := sess.data[key]
	sess.RUnlock()
	return val, ok
}

// Delete deletes a stored session value from the context.
func Delete(ctxt context.Context, key string) {
	sess := ctxt.Value(sessionContextKey).(session)
	sess.Lock()
	delete(sess.data, key)
	sess.Unlock()
}

// GetStore retrieves the session store from the context.
func GetStore(ctxt context.Context) Store {
	st := ctxt.Value(storeContextKey).(Store)
	return st
}

// CookieName retrieves the cookie name from the context.
func CookieName(ctxt context.Context) string {
	return ctxt.Value(cookieNameContextKey).(string)
}

// Destroy destroys a session in the underlying session store.
//
// Note that any existing values will continue to remain in the context after
// destruction. The context should be closed (or destroyed).
//
// If the optional http.ResponseWriter is provided, then an expired cookie will
// be added to the response headers.
func Destroy(ctxt context.Context, res ...http.ResponseWriter) error {
	sessID := ID(ctxt)
	st := GetStore(ctxt)

	if len(res) > 0 {
		http.SetCookie(res[0], &http.Cookie{
			Name:    CookieName(ctxt),
			Expires: time.Now(),
			Value:   "-",
			MaxAge:  -1,
		})
	}

	return st.Destroy(sessID)
}

// Config contains the configuration parameters for the session middleware.
type Config struct {
	// Secret is
	Secret      []byte
	BlockSecret []byte

	// Store is the underlying session store.
	Store Store

	// IDFn is the id generation func.
	IDFn IDFn

	// Name is the cookie name.
	Name string

	// Path is the cookie path.
	Path string

	// Domain is the cookie domain.
	Domain string

	// Expires is the cookie expiration time.
	Expires time.Time

	// MaxAge is the cookie max age.
	MaxAge time.Duration

	// Secure is the cookie secure flag.
	Secure bool

	// HttpOnly is the cookie http only flag.
	HttpOnly bool
}

// Handler provides the goji.Handler for the session middleware.
func (c Config) Handler(h goji.Handler) goji.Handler {
{'fraction_non_alphanumeric': 0.10283631754080177, 'fraction_numerical': 0.0023768024084931073, 'mean_word_length': 3.717488789237668, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7096568', 'n_tokens_mistral': 2065, 'n_tokens_neox': 2001, 'n_words': 678}