package main import ( "context" "encoding/json" "flag" "fmt" "log" "net/http" "os" "time" ) const VTT_URL string = "http://73.188.175.49:30000" func remoteOnline(ctx context.Context, url string) bool { req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { panic(err) } _, err = http.DefaultClient.Do(req) if err != nil { return false } return true } func respondOnline(w http.ResponseWriter, url string, isOnline bool) { data := struct { Online bool `json:"online"` Site string `json:"url"` }{isOnline, url} jsonData, err := json.Marshal(data) if err != nil { http.Error(w, "Error constructing response", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.Write(jsonData) } func vttOnline(w http.ResponseWriter, req *http.Request) { isOnline := remoteOnline(req.Context(), VTT_URL) if !isOnline { log.Println("Foundry VTT is offline") } respondOnline(w, VTT_URL, isOnline) } func vttRedirect(w http.ResponseWriter, req *http.Request) { http.Redirect(w, req, VTT_URL, http.StatusMovedPermanently) } func siteOnline(w http.ResponseWriter, req *http.Request) { const URL string = "https://dnd.jpappel.xyz" isOnline := remoteOnline(req.Context(), URL) if !isOnline { log.Println("Campaign Website is offline") } respondOnline(w, URL, isOnline) } func timeoutMiddleware(next http.Handler, duration time.Duration) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), duration) defer cancel() next.ServeHTTP(w, r.WithContext(ctx)) }) } func main() { port := flag.Int("p", 8080, "the port to listen on") bindAddr := flag.String("b", "", "the adress to bind to (leave empty for all interfaces)") waitTime := flag.Duration("w", 2*time.Second, "the maximum time for a request, unit defaults to ns") flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s [options]\n", os.Args[0]) fmt.Fprintln(os.Stderr, "Options:") flag.PrintDefaults() } flag.Parse() addr := fmt.Sprintf("%s:%d", *bindAddr, *port) mux := http.NewServeMux() vtt := timeoutMiddleware(http.HandlerFunc(vttOnline), *waitTime) site := timeoutMiddleware(http.HandlerFunc(siteOnline), *waitTime) mux.Handle("GET /vtt/status", vtt) mux.HandleFunc("GET /vtt", vttRedirect) mux.Handle("GET /site/status", site) log.Println("Listening on ", addr) log.Fatal(http.ListenAndServe(addr, mux)) }