11 func runWebGUI(cfg *Config) {
12 if cfg.WebGUI.Listen == "" {
15 log.Printf("starting webgui at %s", cfg.WebGUI.Listen)
16 log.Fatal(http.ListenAndServe(cfg.WebGUI.Listen, stack(cfg.logger, cfg.apiOrAssets)))
19 type middleware func(http.Handler) http.Handler
21 var notFound = http.NotFoundHandler()
23 // returns a handler that implements a stack of middlewares.
24 func stack(m ...middleware) http.Handler {
28 return m[0](stack(m[1:]...))
32 func (cfg *Config) logger(next http.Handler) http.Handler {
33 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
36 log.Printf("%.6f %q %q %q", time.Since(t).Seconds(), r.RemoteAddr, r.Method, r.URL.Path)
40 // dispatches /api/ to the API stack, everything else to the static
42 func (cfg *Config) apiOrAssets(next http.Handler) http.Handler {
43 mux := http.NewServeMux()
44 mux.Handle("/api/", stack(cfg.apiHeaders, cfg.apiRoutes))
45 mux.Handle("/", http.FileServer(assetFS()))
49 // adds response headers suitable for API responses
50 func (cfg *Config) apiHeaders(next http.Handler) http.Handler {
51 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
52 w.Header().Set("Content-Type", "application/json")
57 // dispatches API routes
58 func (cfg *Config) apiRoutes(http.Handler) http.Handler {
59 mux := http.NewServeMux()
60 mux.HandleFunc("/api/ping", func(w http.ResponseWriter, r *http.Request) {
61 json.NewEncoder(w).Encode(map[string]interface{}{"time": time.Now().UTC()})
63 mux.HandleFunc("/api/status/controller", func(w http.ResponseWriter, r *http.Request) {
64 timeout := time.Minute
65 if v, err := strconv.ParseInt(r.FormValue("timeout"), 10, 64); err == nil {
66 timeout = time.Duration(v) * time.Second
68 if v, err := strconv.ParseInt(r.FormValue("newerThan"), 10, 64); err == nil {
69 log.Println(v, timeout)
71 // TaskState.Wait(version(v), timeout, r.Context())
74 // rep, v := report(ctlTasks)
75 json.NewEncoder(w).Encode(map[string]interface{}{
83 mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
84 w.WriteHeader(http.StatusNotFound)
85 json.NewEncoder(w).Encode(map[string]string{"error": "not found"})