package util import ( "context" "log" "net" "net/http" "os" "os/signal" "github.com/gin-gonic/gin" ) // Copied from: https://github.com/gin-gonic/gin/blob/59ab588bf597f9f41faee4f217b5659893c2e925/utils.go#L137 func resolveAddress(addr []string) string { switch len(addr) { case 0: if port := os.Getenv("PORT"); port != "" { log.Printf("Environment variable PORT=\"%s\"", port) return ":" + port } log.Printf("Environment variable PORT is undefined. Using port :8080 by default") return ":8080" case 1: return addr[0] default: panic("too many parameters") } } // Runs a gin.Engine instance in a way that can be canceled by an SIGINT func GinRun(e *gin.Engine, debug bool, a ...string) { if debug { gin.SetMode(gin.DebugMode) } else { gin.SetMode(gin.ReleaseMode) } srv := &http.Server{ Addr: resolveAddress(a), Handler: e, } idleConnsClosed := make(chan struct{}) go func() { sigint := make(chan os.Signal, 1) signal.Notify(sigint, os.Interrupt) <-sigint log.Println("Caught SIGINT, shutting down") if err := srv.Shutdown(context.Background()); err != nil { log.Printf("HTTP server Shutdown: %v", err) } close(idleConnsClosed) }() log.Printf("Listening and serving HTTP on %s\n", srv.Addr) if err := srv.ListenAndServe(); err != http.ErrServerClosed { log.Fatalf("HTTP server ListenAndServe: %v", err) } <-idleConnsClosed } func GetRequestIP(c *gin.Context) net.IP { if xff := c.Request.Header.Get("X-Forwarded-For"); xff != "" { return ParseIP(xff) } return ParseIP(c.Request.RemoteAddr) }