cerrado @ 7ff4cac4fc23060a56b9c33a3453c2d26629b699

feat: Add server listen configuration
diff --git a/config.example.scfg b/config.example.scfg
index 3961e51ddb60a7deb021ad48db74525d2eae913e..9de249b5a5f90bf9c59566794da9333add87a06d 100644
--- a/config.example.scfg
+++ b/config.example.scfg
@@ -1,4 +1,9 @@
+# for tcp biding
+# listen-addr tcp://localhost:8080
+listen-addr unix://var/run/cerrado.sock
+
 root-readme /srv/git/README.md
+
 scan /srv/git/ {
     public true
 }
diff --git a/main.go b/main.go
index eedff5eb6a12149528573530facbba8b740bd578..18b73ff0fd202e715f3f6721bdc26d36fcebee0a 100644
--- a/main.go
+++ b/main.go
@@ -4,7 +4,6 @@ import (
 	"context"
 	"flag"
 	"log/slog"
-	"net/http"
 	"os"
 	"os/signal"
 	"time"
@@ -16,7 +15,6 @@ 	"git.gabrielgio.me/cerrado/pkg/worker"
 )
 
 func main() {
-
 	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
 	defer stop()
 	if err := run(ctx); err != nil {
@@ -27,7 +25,7 @@ }
 
 func run(ctx context.Context) error {
 	var (
-		configPath = flag.String("config", "config.example.scfg", "File path for the configuration file")
+		configPath = flag.String("config", "/etc/cerrado.scfg", "File path for the configuration file")
 	)
 
 	flag.Parse()
@@ -46,7 +44,7 @@ 	if err != nil {
 		return err
 	}
 
-	serverTask := worker.NewServerTask(&http.Server{Handler: handler, Addr: "0.0.0.0:8080"})
+	serverTask := worker.NewServerTask(configRepo.GetListenAddr(), handler)
 
 	pool := worker.NewTaskPool()
 	pool.AddTask("http-server", 5*time.Second, serverTask)
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 3e539f7091a7b2b1e39ee96b7bd54136d052fd2b..0e85b5abb5231e21caf6a1a3db5c6168709cc10b 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -32,6 +32,7 @@ 	// fields needs to be exported to cmp to work
 	configuration struct {
 		Scan         *scan
 		RootReadme   string
+		ListenAddr   string
 		Repositories []*GitRepositoryConfiguration
 	}
 
@@ -49,6 +50,7 @@ 	// This holds all the function necessary to ask for configuration
 	// information.
 	ConfigurationRepository struct {
 		rootReadme   string
+		listenAddr   string
 		repositories []*GitRepositoryConfiguration
 	}
 )
@@ -66,6 +68,7 @@ 	}
 
 	repo := &ConfigurationRepository{
 		rootReadme:   config.RootReadme,
+		listenAddr:   config.ListenAddr,
 		repositories: config.Repositories,
 	}
 
@@ -83,6 +86,10 @@
 // GetRootReadme returns root read path
 func (c *ConfigurationRepository) GetRootReadme() string {
 	return c.rootReadme
+}
+
+func (c *ConfigurationRepository) GetListenAddr() string {
+	return c.listenAddr
 }
 
 // GetByName returns configuration of repository for a given name.
@@ -157,6 +164,11 @@ 	if err != nil {
 		return nil, err
 	}
 
+	err = setListenAddr(block, &config.ListenAddr)
+	if err != nil {
+		return nil, err
+	}
+
 	err = setRepositories(block, &config.Repositories)
 	if err != nil {
 		return nil, err
@@ -215,6 +227,7 @@ func defaultConfiguration() *configuration {
 	return &configuration{
 		Scan:         defaultScan(),
 		RootReadme:   "",
+		ListenAddr:   "http//0.0.0.0:8080",
 		Repositories: make([]*GitRepositoryConfiguration, 0),
 	}
 }
@@ -239,6 +252,11 @@
 func setRootReadme(block scfg.Block, readme *string) error {
 	scanDir := block.Get("root-readme")
 	return setString(scanDir, readme)
+}
+
+func setListenAddr(block scfg.Block, listenAddr *string) error {
+	scanDir := block.Get("listen-addr")
+	return setString(scanDir, listenAddr)
 }
 
 func setScan(block scfg.Block, scan *scan) error {
diff --git a/pkg/worker/http.go b/pkg/worker/http.go
index 973775e14ea0374073c0c59af15a908bdf1254e0..c4f99504bf9d8968e05cd4f27e8375af9cad7909 100644
--- a/pkg/worker/http.go
+++ b/pkg/worker/http.go
@@ -2,24 +2,41 @@ package worker
 
 import (
 	"context"
+	"errors"
+	"net"
 	"net/http"
+	"net/url"
+)
+
+var (
+	UnsupportedSchemeErr = errors.New("Ivalid schema, only tcp and unix supported")
 )
 
 type ServerTask struct {
-	server *http.Server
+	addr    string
+	handler http.Handler
 }
 
-func NewServerTask(server *http.Server) *ServerTask {
+func NewServerTask(addr string, handler http.Handler) *ServerTask {
 	return &ServerTask{
-		server: server,
+		addr:    addr,
+		handler: handler,
 	}
 }
 
-func (self *ServerTask) Start(ctx context.Context) error {
+func (s *ServerTask) Start(ctx context.Context) error {
 	done := make(chan error)
+
+	listen, err := getListen(s.addr)
+	if err != nil {
+		return err
+	}
+	server := &http.Server{
+		Handler: s.handler,
+	}
 
 	go func() {
-		done <- self.server.ListenAndServe()
+		done <- server.Serve(listen)
 	}()
 
 	select {
@@ -33,6 +50,26 @@ 	// in case of context canceled it will manually trigger the server to
 	// shutdown, and return its error, which is most cases, but not limited, is
 	// context.Canceled.
 	case <-ctx.Done():
-		return self.server.Shutdown(ctx)
+		return server.Shutdown(ctx)
+	}
+}
+
+func getListen(addr string) (net.Listener, error) {
+	u, err := url.Parse(addr)
+	if err != nil {
+		return nil, err
+	}
+
+	switch u.Scheme {
+	case "tcp":
+		return net.Listen(u.Scheme, u.Host)
+	case "unix":
+		host, err := url.JoinPath("/", u.Host, u.Path)
+		if err != nil {
+			return nil, err
+		}
+		return net.Listen(u.Scheme, host)
+	default:
+		return nil, UnsupportedSchemeErr
 	}
 }