Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#80 add context_legacy.go and context.go for go 1.7 migration #95

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@ Other implementations of the `sessions.Store` interface:
* [github.com/michaeljs1990/sqlitestore](https://github.com/michaeljs1990/sqlitestore) - SQLite
* [github.com/wader/gormstore](https://github.com/wader/gormstore) - GORM (MySQL, PostgreSQL, SQLite)

## Notes
Note about `GetRegistry` changes: As of Go version 1.7, gorilla/sessions uses the Go standard library's `context` package rather than `gorilla/context`. This required changing `GetRegistry` to return a shallow copy of the http Request. Users of the `sessions.GetRegistry` method who are upgrading to Go 1.7 will need to change calls to `sessions.GetRegistry`. For example, this (Go 1.6 and prior):

```
reg := sessions.GetRegistry(req)
```

will need to change to this:

```
var reg *Registry
reg, req = sessions.GetRegistry(req)
```

## License

BSD licensed. See the LICENSE file for details.
22 changes: 22 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// +build go1.7

package sessions

import (
"context"
"net/http"
)

func contextGet(r *http.Request, key contextKey) interface{} {
return r.Context().Value(key)
}

func contextSave(r *http.Request, key contextKey, val interface{}) *http.Request {
ctx := r.Context()
ctx = context.WithValue(ctx, key, val)
return r.WithContext(ctx)
}

func contextClear(r *http.Request) {
// no-op for go1.7+
}
22 changes: 22 additions & 0 deletions context_legacy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// +build !go1.7

package sessions

import (
"net/http"

"github.com/gorilla/context"
)

func contextGet(r *http.Request, key contextKey) interface{} {
return context.Get(r, key)
}

func contextSave(r *http.Request, key contextKey, val interface{}) *http.Request {
context.Set(r, key, val)
return r
}

func contextClear(r *http.Request) {
context.Clear(r)
}
16 changes: 8 additions & 8 deletions sessions.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"fmt"
"net/http"
"time"

"github.com/gorilla/context"
)

// Default flashes key.
Expand Down Expand Up @@ -122,17 +120,17 @@ type contextKey int
const registryKey contextKey = 0

// GetRegistry returns a registry instance for the current request.
func GetRegistry(r *http.Request) *Registry {
registry := context.Get(r, registryKey)
func GetRegistry(r *http.Request) (*Registry, *http.Request) {
registry := contextGet(r, registryKey)
if registry != nil {
return registry.(*Registry)
return registry.(*Registry), r
}
newRegistry := &Registry{
request: r,
sessions: make(map[string]sessionInfo),
}
context.Set(r, registryKey, newRegistry)
return newRegistry
r = contextSave(r, registryKey, newRegistry)
return newRegistry, r
}

// Registry stores sessions used during a request.
Expand Down Expand Up @@ -186,7 +184,9 @@ func init() {

// Save saves all sessions used during the current request.
func Save(r *http.Request, w http.ResponseWriter) error {
return GetRegistry(r).Save(w)
var reg *Registry
reg, r = GetRegistry(r)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there was no registry saved in the request's context, we shouldn't create a new, empty one here, only to throw it away after telling it to save nothing. Instead, separate GetRegistry into its two cases—one that returns an existing registry if it already exists, and one that wraps it and installs a fresh registry if there wasn't one before. This function should use the former and bail early if there was no existing registry.

return reg.Save(w)
}

// NewCookie returns an http.Cookie with the options set. It also sets
Expand Down
8 changes: 6 additions & 2 deletions store.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ type CookieStore struct {
// It returns a new session and an error if the session exists but could
// not be decoded.
func (s *CookieStore) Get(r *http.Request, name string) (*Session, error) {
return GetRegistry(r).Get(s, name)
reg, req := GetRegistry(r)
*r = *req
return reg.Get(s, name)
}

// New returns a session for the given name without adding it to the registry.
Expand Down Expand Up @@ -180,7 +182,9 @@ func (s *FilesystemStore) MaxLength(l int) {
//
// See CookieStore.Get().
func (s *FilesystemStore) Get(r *http.Request, name string) (*Session, error) {
return GetRegistry(r).Get(s, name)
reg, req := GetRegistry(r)
*r = *req
return reg.Get(s, name)
}

// New returns a session for the given name without adding it to the registry.
Expand Down