2024-03-09 23:29:25 -05:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
2024-03-10 04:25:22 -04:00
|
|
|
"log"
|
2024-03-09 23:29:25 -05:00
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
2024-03-10 04:25:22 -04:00
|
|
|
"os/signal"
|
2024-03-09 23:29:25 -05:00
|
|
|
"strings"
|
2024-03-10 04:25:22 -04:00
|
|
|
"syscall"
|
2024-03-09 23:29:25 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
func indexHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
w.Write([]byte("Hello, this is a Unix socket HTTP server in Go!"))
|
|
|
|
}
|
|
|
|
|
2024-03-10 04:25:22 -04:00
|
|
|
func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
w.Write([]byte("healthy"))
|
|
|
|
}
|
|
|
|
|
2024-03-09 23:29:25 -05:00
|
|
|
func main() {
|
|
|
|
socketPath, users := getArgs()
|
|
|
|
os.Remove(socketPath)
|
|
|
|
|
|
|
|
listener, err := net.Listen("unix", socketPath)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
os.Chmod(socketPath, 0700)
|
2024-03-10 04:25:22 -04:00
|
|
|
|
|
|
|
sigc := make(chan os.Signal, 1)
|
|
|
|
signal.Notify(sigc, os.Interrupt, os.Kill, syscall.SIGTERM)
|
|
|
|
go func(c chan os.Signal) {
|
|
|
|
// Wait for a SIGINT or SIGKILL:
|
|
|
|
sig := <-c
|
|
|
|
log.Printf("Caught signal %s: shutting down.", sig)
|
|
|
|
|
|
|
|
listener.Close()
|
|
|
|
os.Exit(0)
|
|
|
|
}(sigc)
|
2024-03-09 23:29:25 -05:00
|
|
|
defer listener.Close()
|
|
|
|
|
|
|
|
for _, user := range strings.Split(users, ",") {
|
|
|
|
setACL(socketPath, user)
|
|
|
|
}
|
|
|
|
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
mux.HandleFunc("/", indexHandler)
|
2024-03-10 04:25:22 -04:00
|
|
|
mux.HandleFunc("/health", healthCheckHandler)
|
2024-03-09 23:29:25 -05:00
|
|
|
|
|
|
|
http.Serve(listener, mux)
|
|
|
|
}
|
|
|
|
|
|
|
|
func setACL(socketPath, user string) {
|
|
|
|
cmd := exec.Command("setfacl", "-m", "u:"+user+":rwx", socketPath)
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
|
|
panic("failed to set ACL: " + err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func getArgs() (string, string) {
|
|
|
|
socketPath := flag.String("socket-path", "/tmp/go-server.sock", "Path to the Unix socket")
|
|
|
|
users := flag.String("users", "", "Comma-separated list of users for ACL")
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
if *users == "" {
|
|
|
|
fmt.Println("You must specify at least one user with --users")
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
return *socketPath, *users
|
|
|
|
}
|