Browse Source

add control socket (HTTP server)

also there is some refactoring on circologd: connection handling,
closing, etc. Not as much as needed, though: shutdown is still unclean,
and websocket clean shutdown is not tested
boyska 5 years ago
parent
commit
1b08df0ce0
2 changed files with 56 additions and 8 deletions
  1. 26 0
      cmd/circologd/http_ctl.go
  2. 30 8
      cmd/circologd/main.go

+ 26 - 0
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})
+	}
+}

+ 30 - 8
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
 			}
 		}