1
0
httpprocprobed/prog/server.go

91 lines
2.5 KiB
Go

/*
httpprocwatchd provides HTTP interface to a list of process' statuses
formatted as JSON.
Copyright (c) 2021 Alexander "Arav" Andreev <me@arav.top>
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 <https://www.gnu.org/licenses/>.
*/
package prog
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")
}
}
}