Files
quake-kube/internal/quake/client/router.go
Kyle Travis 1e1edac3a5 Add prometheus instrumentation, count active ws conns (#8)
* Add prometheus instrumentation, count active ws conns

* Stop bum ticker

* Moving things around

* Handle unspecified host for ws proxy

* Add config reload counter

* metrics: rename conns -> players
2020-08-17 10:59:30 -04:00

111 lines
2.6 KiB
Go

package client
import (
"html/template"
"io"
"io/ioutil"
"net/http"
"net/url"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/prometheus/client_golang/prometheus/promhttp"
quakenet "github.com/criticalstack/quake-kube/internal/quake/net"
)
type Config struct {
ContentServerURL string
ServerAddr string
Files http.FileSystem
}
func NewRouter(cfg *Config) (*echo.Echo, error) {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept},
}))
f, err := cfg.Files.Open("index.html")
if err != nil {
return nil, err
}
defer f.Close()
data, err := ioutil.ReadAll(f)
if err != nil {
return nil, err
}
templates, err := template.New("index").Parse(string(data))
if err != nil {
return nil, err
}
e.Renderer = &TemplateRenderer{templates}
// default route
e.GET("/", func(c echo.Context) error {
return c.Render(http.StatusOK, "index", map[string]string{
"ServerAddr": cfg.ServerAddr,
})
})
e.GET("/metrics", echo.WrapHandler(promhttp.Handler()))
e.GET("/info", func(c echo.Context) error {
m, err := quakenet.GetInfo(cfg.ServerAddr)
if err != nil {
return err
}
return c.JSON(http.StatusOK, m)
})
e.GET("/status", func(c echo.Context) error {
m, err := quakenet.GetStatus(cfg.ServerAddr)
if err != nil {
return err
}
return c.JSON(http.StatusOK, m)
})
// static files
e.GET("/*", echo.WrapHandler(http.FileServer(cfg.Files)))
// Quake3 assets requests must be proxied to the content server. The host
// header is manipulated to ensure that services like CloudFlare will not
// reject requests based upon incorrect host header.
csurl, err := url.Parse(cfg.ContentServerURL)
if err != nil {
return nil, err
}
g := e.Group("/assets")
g.Use(middleware.ProxyWithConfig(middleware.ProxyConfig{
Balancer: middleware.NewRoundRobinBalancer([]*middleware.ProxyTarget{
{URL: csurl},
}),
Transport: &HostHeaderTransport{RoundTripper: http.DefaultTransport, Host: csurl.Host},
}))
return e, nil
}
type HostHeaderTransport struct {
http.RoundTripper
Host string
}
func (t *HostHeaderTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req.Host = t.Host
return t.RoundTripper.RoundTrip(req)
}
type TemplateRenderer struct {
*template.Template
}
func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.ExecuteTemplate(w, name, data)
}