/* httpprocwatchd provides HTTP interface to a list of process' statuses formatted as JSON. Copyright (c) 2021 Alexander "Arav" Andreev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package main import ( "context" "encoding/json" "encoding/xml" "log" "net/http" "time" ) func createAndStartHTTPServer(conf *Configuration) *http.Server { router := http.NewServeMux() router.HandleFunc("/processes", AreProcessesUp(&conf.Processes)) srv := &http.Server{ Addr: conf.ListenAddress, Handler: router, ReadTimeout: 5 * time.Second, WriteTimeout: 5 * time.Second, IdleTimeout: 10 * time.Second, } go func() { if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("ListenAndServe: %s\n", err) } }() return srv } func shutdownHTTPServer(srv *http.Server) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() srv.SetKeepAlivesEnabled(false) if err := srv.Shutdown(ctx); err != nil { log.Fatalf("%s\n", err) } } // AreProcessesUp handles a GET /processes request and sends back status of given // processes. func AreProcessesUp(processes *[]string) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodGet { proclist := NewProcessList() for _, proc := range *processes { isup, _, _ := IsProcessUp(proc) proclist.AddProcess(proc, isup) } if hdr := r.Header.Get("Accept"); hdr == "application/xml" { w.Header().Add("Content-Type", "application/xml") enc := xml.NewEncoder(w) enc.Indent("", "\t") enc.Encode(proclist) } else { w.Header().Add("Content-Type", "application/json") enc := json.NewEncoder(w) enc.SetIndent("", "\t") enc.Encode(proclist) } } else { w.WriteHeader(http.StatusMethodNotAllowed) w.Header().Add("Allow", "GET") } } }