diff --git a/cmd/circologd/http_ctl.go b/cmd/circologd/http_ctl.go new file mode 100644 index 0000000..554869b --- /dev/null +++ b/cmd/circologd/http_ctl.go @@ -0,0 +1,26 @@ +package main + +import ( + "encoding/json" + "net/http" + + "git.lattuga.net/boyska/circolog" + "github.com/gorilla/mux" +) + +func setupHTTPCtl(hub circolog.Hub) *mux.Router { + mux := mux.NewRouter() + mux.HandleFunc("/pause/toggle", togglePause(hub)).Methods("POST") + return mux +} + +func togglePause(hub circolog.Hub) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + hub.Commands <- circolog.HubFullCommand{Command: circolog.CommandPauseToggle} + resp := <-hub.Responses + active := resp.Value.(bool) + w.Header().Set("content-type", "application/json") + enc := json.NewEncoder(w) + enc.Encode(map[string]interface{}{"paused": !active}) + } +} diff --git a/cmd/circologd/main.go b/cmd/circologd/main.go index c554114..054b226 100644 --- a/cmd/circologd/main.go +++ b/cmd/circologd/main.go @@ -16,7 +16,7 @@ import ( func cleanSocket(socket string) { if err := os.Remove(socket); err != nil { - fmt.Fprintln(os.Stderr, socket, ":", err) + fmt.Fprintln(os.Stderr, "Error cleaning", socket, ":", err) } } @@ -28,6 +28,7 @@ func main() { syslogAddr := flag.String("syslog-addr", "127.0.0.1:9514", "Address:port where to listen for syslog messages") queryAddr := flag.String("query-addr", "127.0.0.1:9080", "Address:port where to bind the query service") querySocket := flag.String("query-socket", "", "Path to a unix domain socket for the HTTP server; recommended for security reasons!") + ctlSocket := flag.String("ctl-socket", "/tmp/circologd-ctl.sock", "Path to a unix domain socket for the control server; leave empty to disable") flag.Parse() interrupt := make(chan os.Signal, 1) @@ -59,7 +60,7 @@ func main() { os.Exit(1) } - httpServer := http.Server{Handler: setupHTTP(hub)} + httpQueryServer := http.Server{Handler: setupHTTP(hub)} if *querySocket != "" { fmt.Printf("Binding address `%s` [http]\n", *querySocket) unixListener, err := net.Listen("unix", *querySocket) @@ -69,21 +70,39 @@ func main() { } defer cleanSocket(*querySocket) go func() { - if err := httpServer.Serve(unixListener); err != nil { - fmt.Fprintln(os.Stderr, "error binding:", err) + if err := httpQueryServer.Serve(unixListener); err != nil && err != http.ErrServerClosed { + fmt.Fprintln(os.Stderr, "error binding", *querySocket, ":", err) } }() } else { - httpServer.Addr = *queryAddr + httpQueryServer.Addr = *queryAddr fmt.Printf("Binding address `%s` [http]\n", *queryAddr) go func() { - err := httpServer.ListenAndServe() - if err != nil { + err := httpQueryServer.ListenAndServe() + if err != nil && err != http.ErrServerClosed { + fmt.Fprintln(os.Stderr, "error binding", *queryAddr, ":", err) + } + }() + } + + httpCtlServer := http.Server{Handler: setupHTTPCtl(hub)} + if *ctlSocket != "" { + fmt.Printf("Binding address `%s` [http]\n", *ctlSocket) + unixListener, err := net.Listen("unix", *ctlSocket) + if err != nil { + fmt.Fprintln(os.Stderr, "Error binding HTTP unix domain socket", err) + return + } + defer cleanSocket(*ctlSocket) + go func() { + if err := httpCtlServer.Serve(unixListener); err != nil && err != http.ErrServerClosed { fmt.Fprintln(os.Stderr, "error binding:", err) } }() } + // TODO: now we are ready + for { select { case sig := <-interrupt: @@ -104,9 +123,12 @@ func main() { if sig == syscall.SIGTERM || sig == syscall.SIGINT { log.Println("Quitting because of signal", sig) server.Kill() - if err := httpServer.Close(); err != nil { + if err := httpQueryServer.Shutdown(nil); err != nil { fmt.Fprintln(os.Stderr, "Error closing http server:", err) } + if err := httpCtlServer.Shutdown(nil); err != nil { + fmt.Fprintln(os.Stderr, "Error closing control server:", err) + } return } }