package main import ( "context" "embed" "flag" "fmt" "html/template" "net/http" "os" "os/signal" "time" "git.mstar.dev/mstar/goutils/middleware" "git.mstar.dev/mstar/goutils/other" "github.com/rs/zerolog/hlog" "github.com/rs/zerolog/log" ) const HTML_PREFIX = "" //go:embed templates var embed_templates embed.FS //go:embed static var embed_static embed.FS //go:embed well-known var embed_well_known embed.FS // go: embed robots.txt var embed_robots_txt string // go: embed humans.txt var embed_humans_txt string func main() { other.SetupFlags() portFlag := flag.String("port", "8080", "Set the port. Overwrites env vars") flag.Parse() other.ConfigureLoggingFromCliArgs() mux := http.NewServeMux() mux.HandleFunc("/{$}", handleRoot) // Catchall that just redirects to Hetzner's 10GB speedtest file // TODO: Maybe swap that for a forced zip bomb? mux.Handle( "/", http.RedirectHandler("https://hil-speed.hetzner.com/10GB.bin", http.StatusMovedPermanently), ) mux.HandleFunc("/cat/awawawa", awawaStream) // static files in /static mux.Handle("/static/", http.FileServer(http.FS(embed_static))) // .well-known from /well-known mux.Handle( "/.well-known/", http.StripPrefix("/.well-known/", http.FileServer(http.FS(embed_well_known))), ) // Static files not in /static or /.well-known mux.HandleFunc("/robots.txt", buildHTTPFileReader(embed_robots_txt)) mux.HandleFunc("/humans.txt", buildHTTPFileReader(embed_humans_txt)) server := http.Server{ Addr: ":" + *portFlag, Handler: middleware.ChainMiddlewares(mux, middleware.LoggingMiddleware), } exitChan := make(chan os.Signal, 1) signal.Notify(exitChan, os.Interrupt) go func() { log.Info().Str("addr", server.Addr).Msg("Starting server") if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatal().Err(err).Msg("Server exited unexpectedly") } }() <-exitChan log.Info().Msg("Shutting down server due to Interrupt") ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) defer cancel() err := server.Shutdown(ctx) if err != nil { log.Fatal().Err(err).Msg("Failed to cleanly shut down") } log.Info().Msg("Clean shutdown complete") } func handleRoot(w http.ResponseWriter, r *http.Request) { tmpl, err := template.ParseFS(embed_templates, "templates/index.html") if err != nil { http.Error(w, "Couldn't parse template file", http.StatusInternalServerError) return } err = tmpl.Execute(w, nil) if err != nil { http.Error(w, "Failed to execute template", http.StatusInternalServerError) } } func buildHTTPFileReader(embed_content string) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "%s", embed_content) } } func awawaStream(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html") w.WriteHeader(206) w.Header().Set("Status", "206") genStub( 1024, w, ) // Hardcoded. Firefox & Chrome both have this value and a len of 0 wouldn't work hlog.FromRequest(r).Debug().Msg("Starting stream") i := true // Only run every 0.2 seconds, aka 5 times a second timer := time.Tick(time.Millisecond * 200) for { select { case <-r.Context().Done(): hlog.FromRequest(r).Debug().Msg("Stream done") return case <-timer: if i { fmt.Fprint(w, "a") } else { fmt.Fprint(w, "w") } i = !i } } } func genStub(length int, w http.ResponseWriter) { PreSufLen := len(HTML_PREFIX) + len(HTML_SUFFIX) fmt.Fprint(w, HTML_PREFIX) for i := 0; i < length-PreSufLen; i++ { fmt.Fprint(w, '\u0020') } fmt.Fprint(w, HTML_SUFFIX) }