1
0
httpprocprobed/httpserver.go

87 lines
2.0 KiB
Go

package main
import (
"context"
"encoding/json"
"encoding/xml"
"log"
"net/http"
"strings"
"time"
)
func CreateAndStartHTTPServer(conf *Configuration) *http.Server {
router := http.NewServeMux()
router.HandleFunc("/processes", AreProcessesUp(&conf.Processes, conf.IndentedOutput))
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, indented bool) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
proclist := make(ProcessList)
for _, proc := range *processes {
pids, err := GetProcessPIDs(proc)
proclist[proc] = err == nil && len(pids) > 0
}
switch r.Header.Get("Accept") {
case "application/xml":
w.Header().Add("Content-Type", "application/xml")
enc := xml.NewEncoder(w)
if indented {
enc.Indent("", "\t")
}
enc.Encode(proclist)
case "text/plain":
w.Header().Add("Content-Type", "text/plain")
var s []string
for k, v := range proclist {
if v {
s = append(s, k)
}
}
w.Write([]byte(strings.Join(s, ",")))
default:
w.Header().Add("Content-Type", "application/json")
enc := json.NewEncoder(w)
if indented {
enc.SetIndent("", "\t")
}
enc.Encode(proclist)
}
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Header().Add("Allow", "GET")
}
}
}