github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/blog/content/context/userip/userip.go (about) 1 // Package userip provides functions for extracting a user IP address from a 2 // request and associating it with a Context. 3 package userip 4 5 import ( 6 "fmt" 7 "net" 8 "net/http" 9 10 "golang.org/x/net/context" 11 ) 12 13 // FromRequest extracts the user IP address from req, if present. 14 func FromRequest(req *http.Request) (net.IP, error) { 15 ip, _, err := net.SplitHostPort(req.RemoteAddr) 16 if err != nil { 17 return nil, fmt.Errorf("userip: %q is not IP:port", req.RemoteAddr) 18 } 19 20 userIP := net.ParseIP(ip) 21 if userIP == nil { 22 return nil, fmt.Errorf("userip: %q is not IP:port", req.RemoteAddr) 23 } 24 return userIP, nil 25 } 26 27 // The key type is unexported to prevent collisions with context keys defined in 28 // other packages. 29 type key int 30 31 // userIPkey is the context key for the user IP address. Its value of zero is 32 // arbitrary. If this package defined other context keys, they would have 33 // different integer values. 34 const userIPKey key = 0 35 36 // NewContext returns a new Context carrying userIP. 37 func NewContext(ctx context.Context, userIP net.IP) context.Context { 38 return context.WithValue(ctx, userIPKey, userIP) 39 } 40 41 // FromContext extracts the user IP address from ctx, if present. 42 func FromContext(ctx context.Context) (net.IP, bool) { 43 // ctx.Value returns nil if ctx has no value for the key; 44 // the net.IP type assertion returns ok=false for nil. 45 userIP, ok := ctx.Value(userIPKey).(net.IP) 46 return userIP, ok 47 }