func (ah *apiHandler) RegisterEncoder(mux *http.ServeMux, path string, enc freegeoip.Encoder) { f := http.Handler(freegeoip.NewHandler(ah.conf.DB, enc)) if ah.conf.RateLimiter.Max > 0 { rl := ah.conf.RateLimiter rl.Handler = f f = &rl } origin := ah.conf.Origin if origin == "" { origin = "*" } f = cors(f, origin, "GET", "HEAD") f = prometheus.InstrumentHandler(path, f) mux.Handle(ah.prefix(path), f) }
func main() { addr := flag.String("addr", ":8080", "Address in form of ip:port to listen on") certFile := flag.String("cert", "", "X.509 certificate file") keyFile := flag.String("key", "", "X.509 key file") public := flag.String("public", "", "Public directory to serve at the / endpoint") ipdb := flag.String("db", maxmindFile, "IP database file or URL") updateIntvl := flag.Duration("update", 24*time.Hour, "Database update check interval") retryIntvl := flag.Duration("retry", time.Hour, "Max time to wait before retrying update") useXFF := flag.Bool("use-x-forwarded-for", false, "Use the X-Forwarded-For header when available") silent := flag.Bool("silent", false, "Do not log requests to stderr") redisAddr := flag.String("redis", "127.0.0.1:6379", "Redis address in form of ip:port for quota") redisTimeout := flag.Duration("redis-timeout", 500*time.Millisecond, "Redis read/write timeout") quotaMax := flag.Int("quota-max", 0, "Max requests per source IP per interval; Set 0 to turn off") quotaIntvl := flag.Duration("quota-interval", time.Hour, "Quota expiration interval") version := flag.Bool("version", false, "Show version and exit") pprof := flag.String("pprof", "", "Address in form of ip:port to listen on for pprof") flag.Parse() if *version { fmt.Printf("freegeoip v%s\n", Version) return } rc, err := redis.Dial(*redisAddr) if err != nil { log.Fatal(err) } rc.Timeout = *redisTimeout db, err := openDB(*ipdb, *updateIntvl, *retryIntvl) if err != nil { log.Fatal(err) } runtime.GOMAXPROCS(runtime.NumCPU()) encoders := map[string]http.Handler{ "/csv/": freegeoip.NewHandler(db, &freegeoip.CSVEncoder{UseCRLF: true}), "/xml/": freegeoip.NewHandler(db, &freegeoip.XMLEncoder{Indent: true}), "/json/": freegeoip.NewHandler(db, &freegeoip.JSONEncoder{}), } if *quotaMax > 0 { seconds := int((*quotaIntvl).Seconds()) for path, f := range encoders { encoders[path] = userQuota(rc, *quotaMax, seconds, f, *silent) } } mux := http.NewServeMux() for path, handler := range encoders { mux.Handle(path, handler) } if len(*public) > 0 { mux.Handle("/", http.FileServer(http.Dir(*public))) } handler := CORS(mux, "GET", "HEAD") if !*silent { log.Println("freegeoip server starting on", *addr) go logEvents(db) handler = logHandler(handler) } if *useXFF { handler = freegeoip.ProxyHandler(handler) } if len(*pprof) > 0 { go func() { log.Fatal(http.ListenAndServe(*pprof, nil)) }() } if len(*certFile) > 0 && len(*keyFile) > 0 { err = http.ListenAndServeTLS(*addr, *certFile, *keyFile, handler) } else { err = http.ListenAndServe(*addr, handler) } if err != nil { log.Fatal(err) } }