github.com/xmidt-org/webpa-common@v1.11.9/service/servicehttp/hashFilter.go (about) 1 package servicehttp 2 3 import ( 4 "net/http" 5 6 "github.com/go-kit/kit/log/level" 7 "github.com/xmidt-org/webpa-common/device" 8 "github.com/xmidt-org/webpa-common/logging" 9 "github.com/xmidt-org/webpa-common/service" 10 "github.com/xmidt-org/webpa-common/xhttp/xfilter" 11 ) 12 13 // NewHashFilter constructs an xfilter that enforces device hashing to an instance that represents this server process. 14 // Any request that does not pass the self predicate will be rejected with the reject error. 15 // 16 // The returned filter will check the request's context for a device id, using that to hash with if one is found. 17 // Otherwise, the device key is parsed from the request via device.IDHashParser. 18 func NewHashFilter(a service.Accessor, reject error, self func(string) bool) xfilter.Interface { 19 // allow any nil parameter to simply disable the filtering 20 if a == nil || reject == nil || self == nil { 21 return xfilter.Allow() 22 } 23 24 return xfilter.Func(func(r *http.Request) error { 25 var key []byte 26 27 if id, ok := device.GetID(r.Context()); ok { 28 key = id.Bytes() 29 } else { 30 var err error 31 if key, err = device.IDHashParser(r); err != nil { 32 return err 33 } 34 } 35 36 i, err := a.Get(key) 37 if err != nil { 38 return err 39 } 40 41 if !self(i) { 42 logging.GetLogger(r.Context()).Log(level.Key(), level.ErrorValue(), logging.MessageKey(), "device does not hash to this instance", "hashKey", string(key), logging.ErrorKey(), reject, "instance", i) 43 return reject 44 } 45 46 return nil 47 }) 48 }