package console import ( "net" "github.com/carlosframework/platform/internal/geo" ) // guessInput carries a request's location hints for ONE call. Neither // field is ever stored, logged, audited or echoed (spec §6.5). type guessInput struct { TZ string IP net.IP } // guessResult is a guess in the record vocabulary and its source word. type guessResult struct{ Code, Source string } // guessRegion is spec §6.4: // // 1. filter candidates to eligible ones the policy allows; // 2. nearest among those with a point, from the timezone, else (only // when the timezone is unmappable) the IP; // 3. else the home, ONLY if the home is itself a filtered candidate; // 4. else no guess. func guessRegion(cands []regionCandidate, allows func(code string) bool, in guessInput, loc geo.Locator) (guessResult, bool) { var pick []geo.Candidate homeIn := false for _, c := range cands { if !c.Eligible || !allows(c.Code) { continue } pick = append(pick, geo.Candidate{Code: c.Code, Home: c.Home, AWSRegion: c.AWSRegion}) homeIn = homeIn || c.Home } if len(pick) == 0 { return guessResult{}, false } if p, ok := geo.ZonePoint(in.TZ); ok { if code, ok := geo.Nearest(p, pick); ok { return guessResult{code, "timezone"}, true } } else if loc != nil && in.IP != nil { if p, ok := loc.Locate(in.IP); ok { if code, ok := geo.Nearest(p, pick); ok { return guessResult{code, "ip"}, true } } } if homeIn { return guessResult{"", "default"}, true } return guessResult{}, false }