golang.org/toolchain@v0.0.1-go1.9rc2.windows-amd64/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  //
     4  // This package is an example to accompany https://blog.golang.org/context.
     5  // It is not intended for use by others.
     6  package userip
     7  
     8  import (
     9  	"fmt"
    10  	"net"
    11  	"net/http"
    12  
    13  	"golang.org/x/net/context"
    14  )
    15  
    16  // FromRequest extracts the user IP address from req, if present.
    17  func FromRequest(req *http.Request) (net.IP, error) {
    18  	ip, _, err := net.SplitHostPort(req.RemoteAddr)
    19  	if err != nil {
    20  		return nil, fmt.Errorf("userip: %q is not IP:port", req.RemoteAddr)
    21  	}
    22  
    23  	userIP := net.ParseIP(ip)
    24  	if userIP == nil {
    25  		return nil, fmt.Errorf("userip: %q is not IP:port", req.RemoteAddr)
    26  	}
    27  	return userIP, nil
    28  }
    29  
    30  // The key type is unexported to prevent collisions with context keys defined in
    31  // other packages.
    32  type key int
    33  
    34  // userIPkey is the context key for the user IP address.  Its value of zero is
    35  // arbitrary.  If this package defined other context keys, they would have
    36  // different integer values.
    37  const userIPKey key = 0
    38  
    39  // NewContext returns a new Context carrying userIP.
    40  func NewContext(ctx context.Context, userIP net.IP) context.Context {
    41  	return context.WithValue(ctx, userIPKey, userIP)
    42  }
    43  
    44  // FromContext extracts the user IP address from ctx, if present.
    45  func FromContext(ctx context.Context) (net.IP, bool) {
    46  	// ctx.Value returns nil if ctx has no value for the key;
    47  	// the net.IP type assertion returns ok=false for nil.
    48  	userIP, ok := ctx.Value(userIPKey).(net.IP)
    49  	return userIP, ok
    50  }