diff options
Diffstat (limited to 'content/context/userip/userip.go')
-rw-r--r-- | content/context/userip/userip.go | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/content/context/userip/userip.go b/content/context/userip/userip.go new file mode 100644 index 0000000..3001ade --- /dev/null +++ b/content/context/userip/userip.go @@ -0,0 +1,38 @@ +// Package userip provides functions for extracting a user IP address from a +// request and associating it with a Context. +package userip + +import ( + "fmt" + "net" + "net/http" + "strings" + + "code.google.com/p/go.net/context" +) + +// FromRequest extracts the user IP address from req, if present. +func FromRequest(req *http.Request) (net.IP, error) { + s := strings.SplitN(req.RemoteAddr, ":", 2) + userIP := net.ParseIP(s[0]) + if userIP == nil { + return nil, fmt.Errorf("userip: %q is not IP:port", req.RemoteAddr) + } + return userIP, nil +} + +// The address &key is the context key. +var key struct{} + +// NewContext returns a new Context carrying userIP. +func NewContext(ctx context.Context, userIP net.IP) context.Context { + return context.WithValue(ctx, &key, userIP) +} + +// FromContext extracts the user IP address from ctx, if present. +func FromContext(ctx context.Context) (net.IP, bool) { + // ctx.Value returns nil if ctx has no value for the key; + // the net.IP type assertion returns ok=false for nil. + userIP, ok := ctx.Value(&key).(net.IP) + return userIP, ok +} |