2021-05-03 14:51:53 +02:00
|
|
|
package web
|
|
|
|
|
|
|
|
import (
|
2021-05-05 08:32:35 +02:00
|
|
|
"context"
|
2021-05-03 14:51:53 +02:00
|
|
|
"fmt"
|
|
|
|
"html/template"
|
2021-05-05 08:32:35 +02:00
|
|
|
"net"
|
2021-05-03 14:51:53 +02:00
|
|
|
"net/http"
|
|
|
|
|
2021-05-05 08:32:35 +02:00
|
|
|
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
2021-05-03 14:51:53 +02:00
|
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"go.xsfx.dev/logginghandler"
|
|
|
|
assets "go.xsfx.dev/schnutibox/assets/web"
|
|
|
|
"go.xsfx.dev/schnutibox/internal/config"
|
2021-05-05 08:32:35 +02:00
|
|
|
api "go.xsfx.dev/schnutibox/pkg/api/v1"
|
2021-05-03 14:51:53 +02:00
|
|
|
"go.xsfx.dev/schnutibox/pkg/sselog"
|
2021-05-05 08:32:35 +02:00
|
|
|
"google.golang.org/grpc"
|
|
|
|
"google.golang.org/grpc/reflection"
|
2021-05-03 14:51:53 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func root(w http.ResponseWriter, r *http.Request) {
|
|
|
|
logger := logginghandler.Logger(r)
|
|
|
|
|
|
|
|
t, err := template.ParseFS(assets.Templates, "templates/index.html.tmpl")
|
|
|
|
if err != nil {
|
|
|
|
logger.Error().Err(err).Msg("could not parse template")
|
|
|
|
http.Error(w, "could not parse template", http.StatusInternalServerError)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-05-03 14:54:28 +02:00
|
|
|
if err := t.Execute(w, struct{}{}); err != nil {
|
|
|
|
logger.Error().Err(err).Msg("could not execute template")
|
|
|
|
http.Error(w, "could not execute template", http.StatusInternalServerError)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
2021-05-03 14:51:53 +02:00
|
|
|
}
|
|
|
|
|
2021-05-05 08:32:35 +02:00
|
|
|
func gw(conn string) *runtime.ServeMux {
|
|
|
|
ctx := context.Background()
|
|
|
|
gopts := []grpc.DialOption{grpc.WithInsecure()}
|
|
|
|
s := grpc.NewServer()
|
|
|
|
|
|
|
|
api.RegisterIdentifierServer(s, api.Server{})
|
|
|
|
reflection.Register(s)
|
|
|
|
|
|
|
|
lis, err := net.Listen("tcp", conn)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal().Err(err).Msg("could not listen")
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Info().Msgf("serving GRPC on %s...", conn)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
log.Fatal().Err(s.Serve(lis))
|
|
|
|
}()
|
|
|
|
|
|
|
|
gwmux := runtime.NewServeMux()
|
|
|
|
if err := api.RegisterIdentifierHandlerFromEndpoint(ctx, gwmux, conn, gopts); err != nil {
|
|
|
|
log.Fatal().Err(err).Msg("could not register grpc endpoint")
|
|
|
|
}
|
|
|
|
|
|
|
|
return gwmux
|
|
|
|
}
|
|
|
|
|
2021-05-03 14:51:53 +02:00
|
|
|
func Run(command *cobra.Command, args []string) {
|
|
|
|
// Create host string for serving web.
|
2021-05-05 08:32:35 +02:00
|
|
|
lh := fmt.Sprintf("%s:%d", config.Cfg.Box.Hostname, config.Cfg.Box.Port)
|
|
|
|
lg := fmt.Sprintf("%s:%d", config.Cfg.Box.Hostname, config.Cfg.Box.Grpc)
|
|
|
|
|
|
|
|
// GRPC.
|
2021-05-03 14:51:53 +02:00
|
|
|
|
|
|
|
// Define http handlers.
|
2021-05-05 08:32:35 +02:00
|
|
|
mux := http.NewServeMux()
|
|
|
|
mux.Handle("/", logginghandler.Handler(http.HandlerFunc(root)))
|
|
|
|
mux.Handle("/log", logginghandler.Handler(http.HandlerFunc(sselog.LogHandler)))
|
|
|
|
mux.Handle(
|
2021-05-03 14:51:53 +02:00
|
|
|
"/static/",
|
|
|
|
logginghandler.Handler(
|
|
|
|
http.StripPrefix("/static/", http.FileServer(http.FS(assets.Files))),
|
|
|
|
),
|
|
|
|
)
|
2021-05-05 08:32:35 +02:00
|
|
|
mux.Handle("/metrics", promhttp.Handler())
|
|
|
|
|
|
|
|
mux.Handle("/api/", http.StripPrefix("/api", gw(lg)))
|
2021-05-03 14:51:53 +02:00
|
|
|
|
2021-05-05 08:32:35 +02:00
|
|
|
// Serving http.
|
|
|
|
log.Info().Msgf("serving HTTP on %s...", lh)
|
2021-05-03 14:51:53 +02:00
|
|
|
|
2021-05-05 08:32:35 +02:00
|
|
|
log.Fatal().Err(http.ListenAndServe(lh, logginghandler.Handler(mux))).Msg("goodbye")
|
2021-05-03 14:51:53 +02:00
|
|
|
}
|