package cgi import ( "context" "fmt" "io" "net" "net/http" "net/http/cgi" "os" "sync" "time" "git.capotej.com/capotej/communique/config" ) type Servers struct{} func NewServers() *Servers { return &Servers{} } // Start iterates over all Handlers and starts an internal CGI server for each one // along with ticker for the configured handler interval and blocks forever func (s *Servers) Start(cfg config.Config) { var wg sync.WaitGroup for _, handler := range cfg.Handlers { wg.Add(2) go func(aHandler config.Handler) { defer wg.Done() startCGIServer(aHandler) }(handler) go func(aHandler config.Handler) { defer wg.Done() startTicker(aHandler) }(handler) } wg.Wait() } func startCGIServer(h config.Handler) { cgiHandler := cgi.Handler{Path: h.Exec} server := http.Server{ Handler: &cgiHandler, } sock := fmt.Sprintf("%s.sock", h.Name) os.Remove(sock) unixListener, err := net.Listen("unix", sock) if err != nil { panic(err) } server.Serve(unixListener) } func startTicker(h config.Handler) { // TODO add config for this ticker := time.NewTicker(5 * time.Second) done := make(chan bool) func() { for { select { case <-done: return case _ = <-ticker.C: tick(h) } } }() } func tick(h config.Handler) { sock := fmt.Sprintf("%s.sock", h.Name) httpc := http.Client{ Transport: &http.Transport{ DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { return net.Dial("unix", sock) }, }, } var response *http.Response var err error response, err = httpc.Get("http://unix/" + sock) if err != nil { panic(err) } io.Copy(os.Stdout, response.Body) }