func NewRedisStore(namespace string, host string) (*RedisStore, error) { r := &RedisStore{ namespace: namespace, } r.client = redis.New(host) return r, nil }
func main() { var err error cfgfile := flag.String("config", "server.conf", "set config file") flag.Parse() Config, err = ReadConfig(*cfgfile) if err != nil { log.Fatal(err) } // Set up databases Redis = redis.New(Config.Redis) MySQL, err = sql.Open("mysql", Config.MySQL) if err != nil { log.Fatal(err) } // Set up routing and print server info route() hello() // Run HTTP and HTTPS servers wg := &sync.WaitGroup{} if Config.HTTP.Addr != "" { wg.Add(1) log.Printf("Starting HTTP server on %s", Config.HTTP.Addr) go func() { // Use httpxtra's listener to support Unix sockets. server := http.Server{ Addr: Config.HTTP.Addr, Handler: httpxtra.Handler{ Logger: logger, XHeaders: Config.HTTP.XHeaders, }, } log.Fatal(httpxtra.ListenAndServe(server)) //wg.Done() }() } if Config.HTTPS.Addr != "" { wg.Add(1) log.Printf("Starting HTTPS server on %s", Config.HTTPS.Addr) go func() { server := http.Server{ Addr: Config.HTTPS.Addr, Handler: httpxtra.Handler{Logger: logger}, } log.Fatal(server.ListenAndServeTLS( Config.HTTPS.CrtFile, Config.HTTPS.KeyFile)) //wg.Done() }() } wg.Wait() }
func main() { redis_client = redis.New("127.0.0.1:6379") queue_name_re := "([a-zA-Z0-9]+)$" remux.HandleFunc("^/$", IndexHandler) remux.HandleFunc("^/q/"+queue_name_re, queueHandler) server := http.Server{ Addr: ":8080", Handler: remux.DefaultServeMux, Logger: logger, } server.ListenAndServe() }
func TestRateLimiter(t *testing.T) { counter := struct { sync.Mutex n int }{} hf := func(w http.ResponseWriter, r *http.Request) { counter.Lock() counter.n++ counter.Unlock() } kmf := func(r *http.Request) string { return "rate-limiter-test" } rl := &RateLimiter{ Redis: redis.New(), Max: 2, Interval: time.Second, KeyMaker: KeyMakerFunc(kmf), Handler: http.HandlerFunc(hf), } mux := http.NewServeMux() mux.Handle("/", rl) s := httptest.NewServer(mux) defer s.Close() for i := 0; i < 3; i++ { resp, err := http.Get(s.URL) if err != nil { t.Fatal(err) } resp.Body.Close() if resp.StatusCode == http.StatusServiceUnavailable { t.Skip("Redis unavailable, cannot proceed") } if resp.StatusCode != http.StatusOK { if resp.StatusCode == http.StatusForbidden && i != 2 { t.Fatal(resp.Status) } } lim, _ := strconv.Atoi(resp.Header.Get("X-RateLimit-Limit")) rem, _ := strconv.Atoi(resp.Header.Get("X-RateLimit-Remaining")) res, _ := strconv.Atoi(resp.Header.Get("X-RateLimit-Reset")) switch { case i == 0 && lim == 2 && rem == 1 && res > 0: case (i == 1 || i == 2) && lim == 2 && rem == 0 && res > 0: default: log.Fatalf("Unexpected values: limit=%d, remaining=%d, reset=%d", lim, rem, res) } } }
func main() { configFile := flag.String("c", "%name%.conf", "") logFile := flag.String("l", "", "") flag.Usage = func() { fmt.Println("Usage: %name% [-c %name%.conf] [-l logfile]") os.Exit(1) } flag.Parse() var err error config, err := loadConfig(*configFile) if err != nil { log.Fatal(err) } // Initialize log. if *logFile != "" { setLog(*logFile) } // Parse templates. HTML = html.Must(html.ParseGlob(config.TemplatesDir + "/*.html")) TEXT = text.Must(text.ParseGlob(config.TemplatesDir + "/*.txt")) // Set up databases. rc := redis.New(config.DB.Redis) db, err := sql.Open("mysql", config.DB.MySQL) if err != nil { log.Fatal(err) } // Set GOMAXPROCS and show server info. var cpuinfo string if n := runtime.NumCPU(); n > 1 { runtime.GOMAXPROCS(n) cpuinfo = fmt.Sprintf("%d CPUs", n) } else { cpuinfo = "1 CPU" } log.Printf("%s %s (%s)", APPNAME, VERSION, cpuinfo) // Start HTTP server. s := new(httpServer) s.init(config, rc, db) go s.ListenAndServe() go s.ListenAndServeTLS() // Sleep forever. select {} }
func newTestHandler(db *freegeoip.DB) http.Handler { return NewHandler(&HandlerConfig{ Prefix: "/api", PublicDir: ".", DB: db, RateLimiter: RateLimiter{ Redis: redis.New(), Max: 5, Interval: time.Second, KeyMaker: KeyMakerFunc(func(r *http.Request) string { return "handler-test" }), }, }) }
func main() { cfgfile := flag.String("c", "%name%.conf", "set config file") flag.Usage = func() { fmt.Println("Usage: %name% [-c %name%.conf]") os.Exit(1) } flag.Parse() var err error cfg, err = LoadConfig(*cfgfile) if err != nil { log.Fatal(err) } // Set up databases. Redis = redis.New(cfg.DB.Redis) MySQL, err = sql.Open("mysql", cfg.DB.MySQL) if err != nil { log.Fatal(err) } // Print server info and set up HTTP routes. hello() RouteHTTP() // Run HTTP and HTTPS servers. wg := &sync.WaitGroup{} if cfg.HTTP.Addr != "" { wg.Add(1) go ListenHTTP() } if cfg.HTTPS.Addr != "" { wg.Add(1) go ListenHTTPS() } wg.Wait() }
func (s *redisConfigSource) newClient(db int) *redis.Client { return redis.New(s.connectionURL(db)) }
// GeoipHandler handles GET on /csv, /xml and /json. func GeoipHandler() http.HandlerFunc { db, err := sql.Open("sqlite3", conf.IPDB.File) if err != nil { panic(err) } _, err = db.Exec("PRAGMA cache_size=" + conf.IPDB.CacheSize) if err != nil { panic(err) } rc := redis.New(conf.Redis...) return func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": w.Header().Set("Access-Control-Allow-Origin", "*") case "OPTIONS": w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Content-Type", "text/plain") w.Header().Set("Access-Control-Allow-Methods", "GET") w.Header().Set("Access-Control-Allow-Headers", "X-Requested-With") w.WriteHeader(200) return default: w.Header().Set("Allow", "GET, OPTIONS") http.Error(w, http.StatusText(405), 405) return } // GET // Check quota var ipkey string if ip, _, err := net.SplitHostPort(r.RemoteAddr); err != nil { ipkey = r.RemoteAddr // support for XHeaders } else { ipkey = ip } if qcs, err := rc.Get(ipkey); err != nil { if conf.Debug { log.Println("Redis error:", err.Error()) } http.Error(w, http.StatusText(503), 503) // redis down return } else if qcs == "" { if err := rc.Set(ipkey, "1"); err == nil { rc.Expire(ipkey, conf.Limit.Expire) } } else if qc, _ := strconv.Atoi(qcs); qc < conf.Limit.MaxRequests { rc.Incr(ipkey) } else { // Out of quota, soz :( http.Error(w, http.StatusText(403), 403) return } // Parse URL and build the query. var ip string a := strings.SplitN(r.URL.Path, "/", 3) if len(a) == 3 && a[2] != "" { // e.g. /csv/google.com addrs, err := net.LookupHost(a[2]) if err != nil { http.Error(w, http.StatusText(404), 404) return } ip = addrs[0] } else { ip = ipkey } geoip, err := GeoipLookup(db, ip) if err != nil { http.NotFound(w, r) return } switch a[1][0] { case 'c': w.Header().Set("Content-Type", "application/csv") fmt.Fprintf(w, `"%s","%s","%s","%s","%s","%s",`+ `"%s","%0.4f","%0.4f","%s","%s"`+"\r\n", geoip.Ip, geoip.CountryCode, geoip.CountryName, geoip.RegionCode, geoip.RegionName, geoip.CityName, geoip.ZipCode, geoip.Latitude, geoip.Longitude, geoip.MetroCode, geoip.AreaCode) case 'j': resp, err := json.Marshal(geoip) if err != nil { if conf.Debug { log.Println("JSON error:", err.Error()) } http.NotFound(w, r) return } callback := r.FormValue("callback") if callback != "" { w.Header().Set("Content-Type", "text/javascript") fmt.Fprintf(w, "%s(%s);", callback, resp) } else { w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, "%s", resp) } case 'x': w.Header().Set("Content-Type", "application/xml") resp, err := xml.MarshalIndent(geoip, "", " ") if err != nil { if conf.Debug { log.Println("XML error:", err.Error()) } http.Error(w, http.StatusText(500), 500) return } fmt.Fprintf(w, xml.Header+"%s\n", resp) } } }
func (q *RedisQuota) Setup(args ...string) { redis.MaxIdleConnsPerAddr = 5000 q.c = redis.New(args...) q.c.Timeout = time.Duration(1500) * time.Millisecond }
func redisClear() { c := redis.New(addr) c.FlushAll() }
func (q *redisQuota) init(cf *configFile) { redis.MaxIdleConnsPerAddr = 5000 q.cf = cf q.rc = redis.New(cf.Redis...) q.rc.Timeout = time.Duration(1500) * time.Millisecond }
func save_to_redis(key string, value string) { redis_client := redis.New("127.0.0.1:6379") redis_client.Set(key, value) }
func main() { cfgfile := flag.String("c", "%name%.conf", "") keygen := flag.Bool("k", false, "") flag.Usage = func() { fmt.Println("Usage: %name% [-k] [-c %name%.conf]") os.Exit(1) } flag.Parse() if *keygen { fmt.Println(RandHex(16)) return } var err error cfg, err = LoadConfig(*cfgfile) if err != nil { log.Fatal(err) } // Set up databases. Redis = redis.New(cfg.DB.Redis) MySQL, err = sql.Open("mysql", cfg.DB.MySQL) if err != nil { log.Fatal(err) } // Load HTML and plain text templates. LoadTemplates() // Set up session keys Session = sessions.NewCookieStore( []byte(cfg.Session.AuthKey), []byte(cfg.Session.CryptKey), ) // Public html. DocumentRoot = http.FileServer(http.Dir(cfg.DocumentRoot)) // Set GOMAXPROCS and show server info. var cpuinfo string if n := runtime.NumCPU(); n > 1 { runtime.GOMAXPROCS(n) cpuinfo = fmt.Sprintf("%d CPUs", n) } else { cpuinfo = "1 CPU" } log.Printf("%s v%s (%s)", APPNAME, VERSION, cpuinfo) // Start email delivery goroutine. go DeliverEmail() // Run HTTP and HTTPS servers. wg := &sync.WaitGroup{} if cfg.HTTP.Addr != "" { wg.Add(1) go ListenHTTP() } if cfg.HTTPS.Addr != "" { wg.Add(1) go ListenHTTPS() } wg.Wait() }
func (q *RedisQuota) Setup(args ...string) { q.c = redis.New(args...) q.c.Timeout = time.Duration(800) * time.Millisecond }
func main() { var err error cfgfile := flag.String("config", "config.xml", "set config file") sessKey := flag.Bool("keygen", false, "dump random key and exit") flag.Parse() if *sessKey { fmt.Println(RandHex(24)) return } Config, err = ReadConfig(*cfgfile) if err != nil { log.Fatal(err) } // Load templates Tmpl, err = LoadTemplates(Config.TemplatePath, "_base.html") if err != nil { log.Fatal(err) } // Set up databases Redis = redis.New(Config.Redis) MySQL, err = sql.Open("mymysql", Config.MySQL) if err != nil { log.Fatal(err) } // Set up session keys Session = sessions.NewCookieStore(Config.SessionKey) // Public handlers http.HandleFunc("/", IndexHandler) http.HandleFunc("/static/", StaticHandler) http.HandleFunc("/legal.txt", StaticHandler) http.HandleFunc("/favicon.ico", StaticHandler) // Sign Up http.HandleFunc("/signup/", https(unauthenticated(SignUpHandler))) http.HandleFunc("/signup/confirm/", SignUpConfirmHandler) // Sign In and Out http.HandleFunc("/signin/", https(unauthenticated(SignInHandler))) http.HandleFunc("/signout/", SignOutHandler) // Lost password http.HandleFunc("/recovery/", https(unauthenticated(RecoveryHandler))) http.HandleFunc("/recovery/confirm/", RecoveryConfirmHandler) // Signed In handlers http.HandleFunc("/main/", authenticated(MainHandler)) http.HandleFunc("/settings/", https(authenticated(SettingsHandler))) // Custom Handler handler := httpxtra.Handler{ Logger: logger, XHeaders: Config.XHeaders, } // HTTP Server server := http.Server{ Addr: Config.Addr, Handler: handler, } numCPU := runtime.NumCPU() label := "CPU" if numCPU > 1 { label += "s" } runtime.GOMAXPROCS(numCPU) log.Printf("%s v%s (%d %s)", APPNAME, VERSION, numCPU, label) wg := &sync.WaitGroup{} if Config.Addr != "" { wg.Add(1) log.Printf("Starting HTTP server on %s", Config.Addr) go func() { // Use our listener to support Unix sockets. log.Fatal(httpxtra.ListenAndServe(server)) wg.Done() }() } if Config.SSL.Addr != "" { wg.Add(1) log.Printf("Starting HTTPS server on %s", Config.SSL.Addr) go func() { https := server https.Addr = Config.SSL.Addr // No Unix sockets for HTTPS. duh! log.Fatal(https.ListenAndServeTLS( Config.SSL.CertFile, Config.SSL.KeyFile)) wg.Done() }() } wg.Wait() }
*/ package main import ( "fmt" docopt "github.com/docopt/docopt.go" "github.com/fiorix/go-redis/redis" hpr_utils "github.com/ncode/hot-potato-router/utils" "strconv" "strings" ) var ( cfg = hpr_utils.NewConfig() rc = redis.New(cfg.Options["redis"]["server_list"]) ) func main() { usage := `Hot Potato Router Control Usage: hprctl add <vhost> <backend_ip:port> [--weight=<n>] hprctl del <vhost> <backend_ip:port> [--weight=<n>] hprctl show <vhost> hprctl list Args: add add a new vhost and backend dell del a vhost and a backend show show all backends from a given vhost
func main() { var err error cfgfile := flag.String("config", "config.xml", "set config file") sessKey := flag.Bool("keygen", false, "dump random key and exit") flag.Parse() if *sessKey { fmt.Println(RandHex(16)) return } Config, err = ReadConfig(*cfgfile) if err != nil { log.Fatal(err) } // Load templates Tmpl = template.Must(template.ParseGlob(Config.TemplatesDirectory)) if err != nil { log.Fatal(err) } // Set up databases Redis = redis.New(Config.Redis) MySQL, err = sql.Open("mysql", Config.MySQL) if err != nil { log.Fatal(err) } // Set up session keys Session = sessions.NewCookieStore( Config.Session.AuthKey, Config.Session.CryptKey) // Set up routing and print server info route() hello() // Run HTTP and HTTPS servers wg := &sync.WaitGroup{} if Config.HTTP.Addr != "" { wg.Add(1) log.Printf("Starting HTTP server on %s", Config.HTTP.Addr) go func() { // Use httpxtra's listener to support Unix sockets. server := http.Server{ Addr: Config.HTTP.Addr, Handler: httpxtra.Handler{ Logger: logger, XHeaders: Config.HTTP.XHeaders, }, } log.Fatal(httpxtra.ListenAndServe(server)) wg.Done() }() } if Config.HTTPS.Addr != "" { wg.Add(1) log.Printf("Starting HTTPS server on %s", Config.HTTPS.Addr) go func() { server := http.Server{ Addr: Config.HTTPS.Addr, Handler: httpxtra.Handler{Logger: logger}, } log.Fatal(server.ListenAndServeTLS( Config.HTTPS.CrtFile, Config.HTTPS.KeyFile)) wg.Done() }() } wg.Wait() }
// GeoipHandler handles GET on /csv, /xml and /json. func GeoipHandler() http.HandlerFunc { db, err := sql.Open("sqlite3", conf.IPDB.File) if err != nil { log.Fatal(err) } _, err = db.Exec("PRAGMA cache_size=" + conf.IPDB.CacheSize) if err != nil { log.Fatal(err) } stmt, err := db.Prepare(query) if err != nil { log.Fatal(err) } //defer stmt.Close() rc := redis.New(conf.Redis...) return func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": w.Header().Set("Access-Control-Allow-Origin", "*") case "OPTIONS": w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Content-Type", "text/plain") w.Header().Set("Access-Control-Allow-Methods", "GET") w.Header().Set("Access-Control-Allow-Headers", "X-Requested-With") w.WriteHeader(200) return default: w.Header().Set("Allow", "GET, OPTIONS") http.Error(w, http.StatusText(405), 405) return } // GET continuing... var ( ip, ipkey string err error ok bool ) if ip, _, err = net.SplitHostPort(r.RemoteAddr); err != nil { ipkey = r.RemoteAddr // Support for XHeaders } else { ipkey = ip } // Check quota if ok, err = HasQuota(rc, &ipkey); err != nil { // Redis down? if conf.Debug { log.Println("Redis error:", err.Error()) } http.Error(w, http.StatusText(503), 503) return } else if !ok { // Over quota, soz :( http.Error(w, http.StatusText(403), 403) return } // Parse URL (e.g. /csv/ip, /xml/) a := strings.SplitN(r.URL.Path, "/", 3) if len(a) == 3 && a[2] != "" { addrs, err := net.LookupHost(a[2]) if err != nil { // DNS lookup failed, assume host not found. http.Error(w, http.StatusText(404), 404) return } ip = addrs[0] } else { ip = ipkey } // Query the db geoip, err := GeoipLookup(stmt, ip) if err != nil { http.NotFound(w, r) return } switch a[1][0] { case 'c': // csv w.Header().Set("Content-Type", "application/csv") fmt.Fprintf(w, `"%s","%s","%s","%s","%s","%s",`+ `"%s","%0.4f","%0.4f","%s","%s"`+"\r\n", geoip.Ip, geoip.CountryCode, geoip.CountryName, geoip.RegionCode, geoip.RegionName, geoip.CityName, geoip.ZipCode, geoip.Latitude, geoip.Longitude, geoip.MetroCode, geoip.AreaCode) case 'j': // json resp, err := json.Marshal(geoip) if err != nil { if conf.Debug { log.Println("JSON error:", err.Error()) } http.NotFound(w, r) return } callback := r.FormValue("callback") if callback != "" { w.Header().Set("Content-Type", "text/javascript") fmt.Fprintf(w, "%s(%s);", callback, resp) } else { w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, "%s", resp) } case 'x': // xml w.Header().Set("Content-Type", "application/xml") resp, err := xml.MarshalIndent(geoip, "", " ") if err != nil { if conf.Debug { log.Println("XML error:", err.Error()) } http.Error(w, http.StatusText(500), 500) return } fmt.Fprintf(w, xml.Header+"%s\n", resp) case 'm': // map. has to render a html template w.Header().Set("Content-Type", "text/html; charset=utf-8") templates.ExecuteTemplate(w, "map.html", geoip) } } }
// New creates, initializes and returns a new instance of RestMQ. // RestMQ instances are thread-safe. func New(opts string) *RestMQ { return &RestMQ{redis.New(opts)} }