func newRateLimiter(c *Config) (*httprl.RateLimiter, error) { var backend httprl.Backend switch c.RateLimitBackend { case "map": m := httprl.NewMap(1) m.Start() backend = m case "redis": addrs := strings.Split(c.RedisAddr, ",") rc, err := redis.NewClient(addrs...) if err != nil { return nil, err } rc.SetTimeout(c.RedisTimeout) backend = redisrl.New(rc) case "memcache": addrs := strings.Split(c.MemcacheAddr, ",") mc := memcache.New(addrs...) mc.Timeout = c.MemcacheTimeout backend = memcacherl.New(mc) default: return nil, fmt.Errorf("unsupported backend: %q" + c.RateLimitBackend) } rl := &httprl.RateLimiter{ Backend: backend, Limit: c.RateLimitLimit, Interval: int32(c.RateLimitInterval.Seconds()), ErrorLog: c.errorLogger(), //Policy: httprl.AllowPolicy, } return rl, nil }
// Run is the entrypoint for the freegeoip daemon tool. func Run() error { flag.Parse() if *flVersion { fmt.Printf("freegeoip v%s\n", Version) return nil } if *flLogToStdout { log.SetOutput(os.Stdout) } log.SetPrefix("[freegeoip] ") addrs := strings.Split(*flRedisAddr, ",") rc, err := redis.NewClient(addrs...) if err != nil { return err } rc.SetTimeout(*flRedisTimeout) db, err := openDB(*flDB, *flUpdateIntvl, *flRetryIntvl) if err != nil { return err } go watchEvents(db) ah := NewHandler(&HandlerConfig{ Prefix: *flAPIPrefix, Origin: *flCORSOrigin, PublicDir: *flPublicDir, DB: db, RateLimiter: RateLimiter{ Redis: rc, Max: *flQuotaMax, Interval: *flQuotaIntvl, }, }) if !*flSilent { ah = gorilla.CombinedLoggingHandler(os.Stderr, ah) } if *flUseXFF { ah = freegeoip.ProxyHandler(ah) } if len(*flInternalServer) > 0 { http.Handle("/metrics", prometheus.Handler()) log.Println("freegeoip internal server starting on", *flInternalServer) go func() { log.Fatal(http.ListenAndServe(*flInternalServer, nil)) }() } if *flHTTPAddr != "" { log.Println("freegeoip http server starting on", *flHTTPAddr) srv := &http.Server{ Addr: *flHTTPAddr, Handler: ah, ReadTimeout: *flReadTimeout, WriteTimeout: *flWriteTimeout, ConnState: ConnStateMetrics(httpConnsGauge), } go func() { log.Fatal(srv.ListenAndServe()) }() } if *flHTTPSAddr != "" { log.Println("freegeoip https server starting on", *flHTTPSAddr) srv := &http.Server{ Addr: *flHTTPSAddr, Handler: ah, ReadTimeout: *flReadTimeout, WriteTimeout: *flWriteTimeout, ConnState: ConnStateMetrics(httpsConnsGauge), } http2.ConfigureServer(srv, nil) go func() { log.Fatal(srv.ListenAndServeTLS(*flCertFile, *flKeyFile)) }() } select {} }