merp/server.go

108 lines
2.7 KiB
Go

package merp
//3456789112345676892123456789312345678941234567895123456789612345678971234567898
import "encoding/json"
import "fmt"
import "net/http"
import "os"
import "time"
//import "github.com/rs/zerolog/log"
import "github.com/didip/tollbooth"
import "github.com/didip/tollbooth_gin"
import "github.com/gin-gonic/gin"
import "github.com/dn365/gin-zerolog"
import "github.com/thoas/stats"
// ServeForever causes merp to serve http forever
func ServeForever() {
s := getServer()
s.ListenAndServe()
}
func getHealthCheckHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
result := gin.H{
"status": "ok",
"now": time.Now().UTC().Format(time.RFC3339),
}
json, err := json.Marshal(result)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(json)
}
}
func getStatsHandler(middleware *stats.Stats) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
stats := middleware.Data()
b, _ := json.Marshal(stats)
w.Write(b)
}
}
func getRouter() *gin.Engine {
if os.Getenv("DEBUG") == "" {
gin.SetMode(gin.ReleaseMode)
}
limiter := tollbooth.NewLimiter(5, nil)
statsMiddleware := stats.New()
// empty router
r := gin.New()
// wrap panics:
r.Use(gin.Recovery())
// attach logger middleware
r.Use(ginzerolog.Logger("gin"))
r.Use(func(c *gin.Context) {
beginning, recorder := statsMiddleware.Begin(c.Writer)
c.Next()
statsMiddleware.End(beginning, stats.WithRecorder(recorder))
})
r.GET("/.well-known/healthcheck.json", gin.WrapF(getHealthCheckHandler()))
r.GET("/admin/healthcheck.json", gin.WrapF(getHealthCheckHandler()))
r.GET("/admin/stats.json", gin.WrapF(getStatsHandler(statsMiddleware)))
r.GET("/admin/other.json", gin.WrapF(getStatsHandler(statsMiddleware)))
// call it, it returns the appropriate handler function
// so we can execute some code at startup time
// and not just request time
r.GET("/merp/for/:thing", tollbooth_gin.LimitHandler(limiter), handleNewMerp())
r.GET("/get/latest/merp/for/:thing", tollbooth_gin.LimitHandler(limiter), getLatestMerp())
r.GET("/get/latest/merps", tollbooth_gin.LimitHandler(limiter), getLatestMerps())
r.GET("/get/merps/for/:thing", tollbooth_gin.LimitHandler(limiter), getLatestMerps())
return r
}
func getServer() *http.Server {
r := getRouter()
port := "8080"
if os.Getenv("PORT") != "" {
port = os.Getenv("PORT")
}
s := &http.Server{
Addr: fmt.Sprintf(":%s", port),
Handler: r,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
return s
}