package main import ( "context" "errors" "fmt" "io/fs" "isle/daemon" "isle/toolkit" "net" "net/http" "os" "dev.mediocregopher.com/mediocre-go-lib.git/mctx" "dev.mediocregopher.com/mediocre-go-lib.git/mlog" ) const ( daemonHTTPSocketDefaultPath = "/tmp/isle-daemon.sock" daemonHTTPSocketPathEnvVar = "ISLE_DAEMON_HTTP_SOCKET_PATH" daemonHTTPRPCPath = "/rpc/v0.json" ) func httpSocketPath() string { return toolkit.EnvOr( daemonHTTPSocketPathEnvVar, func() string { return daemonHTTPSocketDefaultPath }, ) } func newHTTPServer( ctx context.Context, logger *mlog.Logger, daemonInst *daemon.Daemon, ) ( *http.Server, error, ) { socketPath := httpSocketPath() ctx = mctx.Annotate(ctx, "socketPath", socketPath) if err := os.Remove(socketPath); errors.Is(err, fs.ErrNotExist) { // No problem } else if err != nil { return nil, fmt.Errorf( "removing %q prior to listening: %w", socketPath, err, ) } else { logger.WarnString( ctx, "Deleted existing socket file prior to listening, it's possible a previous daemon failed to shutdown gracefully", ) } l, err := net.Listen("unix", socketPath) if err != nil { return nil, fmt.Errorf( "listening on socket %q: %w", socketPath, err, ) } if err := os.Chmod(socketPath, 0660); err != nil { return nil, fmt.Errorf( "setting permissions of %q to 0660: %w", socketPath, err, ) } logger.Info(ctx, "HTTP server socket created") httpMux := http.NewServeMux() httpMux.Handle(daemonHTTPRPCPath, daemonInst.HTTPRPCHandler()) srv := &http.Server{Handler: httpMux} go func() { if err := srv.Serve(l); !errors.Is(err, http.ErrServerClosed) { logger.Fatal(ctx, "HTTP server unexpectedly shut down", err) } }() return srv, nil }