From b3a29c6caf095f2489d3b1a129ea8224a9e59f4b Mon Sep 17 00:00:00 2001 From: Carlos A Becker Date: Wed, 21 Dec 2022 11:06:05 -0300 Subject: [PATCH] feat: HTTP Server to support go get Signed-off-by: Carlos A Becker --- server/config/config.go | 18 ++++++++++----- server/http.go | 50 +++++++++++++++++++++++++++++++++++++++++ server/server.go | 31 +++++++++++++++++++++---- 3 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 server/http.go diff --git a/server/config/config.go b/server/config/config.go index e26e923eb20ca59823c13c1aa2145116915f2ec4..ea4c773c859de251e802fd19b9881d52e56860d0 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -55,6 +55,13 @@ type DBConfig struct { SSLMode bool `env:"SSL_MODE" envDefault:"false"` } +// HTTPConfig is the HTTP server config. +type HTTPConfig struct { + Enabled bool `env:"ENABLED" envDefault:"true"` + Port int `env:"PORT" envDefault:"8080"` + Domain string `env:"DOMAIN" envDefault:"localhost"` // used for go get +} + // URL returns a database URL for the configuration. func (d *DBConfig) URL() *url.URL { switch d.Driver { @@ -88,9 +95,10 @@ func (d *DBConfig) URL() *url.URL { type Config struct { Host string `env:"HOST" envDefault:"localhost"` - SSH SSHConfig `env:"SSH" envPrefix:"SSH_"` - Git GitConfig `env:"GIT" envPrefix:"GIT_"` - Db DBConfig `env:"DB" envPrefix:"DB_"` + SSH SSHConfig `env:"SSH" envPrefix:"SSH_"` + Git GitConfig `env:"GIT" envPrefix:"GIT_"` + HTTP HTTPConfig `env:"HTTP" envPrefix:"HTTP_"` + Db DBConfig `env:"DB" envPrefix:"DB_"` ServerName string `env:"SERVER_NAME" envDefault:"Soft Serve"` AnonAccess proto.AccessLevel `env:"ANON_ACCESS" envDefault:"read-only"` @@ -174,12 +182,12 @@ func DefaultConfig() *Config { cfg.InitialAdminKeys[i] = pk } // init data path and db - if err := os.MkdirAll(cfg.RepoPath(), 0755); err != nil { + if err := os.MkdirAll(cfg.RepoPath(), 0o755); err != nil { log.Fatalln(err) } switch cfg.Db.Driver { case "sqlite": - if err := os.MkdirAll(filepath.Dir(cfg.DBPath()), 0755); err != nil { + if err := os.MkdirAll(filepath.Dir(cfg.DBPath()), 0o755); err != nil { log.Fatalln(err) } db, err := sqlite.New(cfg.DBPath()) diff --git a/server/http.go b/server/http.go new file mode 100644 index 0000000000000000000000000000000000000000..c2273420c66cb8f2d5d72197e4da63afd40ffa80 --- /dev/null +++ b/server/http.go @@ -0,0 +1,50 @@ +package server + +import ( + "html/template" + "log" + "net" + "net/http" + "strconv" + "strings" + "time" + + "github.com/charmbracelet/soft-serve/server/config" +) + +func newHTTPServer(cfg *config.Config) *http.Server { + r := http.NewServeMux() + r.HandleFunc("/", repoIndexHandler(cfg)) + return &http.Server{ + Addr: net.JoinHostPort(cfg.Host, strconv.Itoa(cfg.HTTP.Port)), + Handler: r, + ReadHeaderTimeout: time.Second * 10, + ReadTimeout: time.Second * 10, + WriteTimeout: time.Second * 10, + MaxHeaderBytes: http.DefaultMaxHeaderBytes, + } +} + +var repoIndexHTMLTpl = template.Must(template.New("index").Parse(` + + + + +`)) + +func repoIndexHandler(cfg *config.Config) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + repo := strings.Split(strings.TrimPrefix(r.URL.Path, "/"), "/")[0] + log.Println("serving index for", repo) + if err := repoIndexHTMLTpl.Execute(w, struct { + Repo string + Config config.Config + }{ + Repo: repo, + Config: *cfg, + }); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + } +} diff --git a/server/server.go b/server/server.go index 6b30bd800621de74c7f10d416af9ba7ec822ba4d..2079fba5fd68a59ff6d297111ed669337006ec73 100644 --- a/server/server.go +++ b/server/server.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "log" + "net/http" "time" cm "github.com/charmbracelet/soft-serve/server/cmd" @@ -21,9 +22,10 @@ import ( // Server is the Soft Serve server. type Server struct { - SSHServer *ssh.Server - GitServer *daemon.Daemon - Config *config.Config + SSHServer *ssh.Server + GitServer *daemon.Daemon + HTTPServer *http.Server + Config *config.Config } // NewServer returns a new *ssh.Server configured to serve Soft Serve. The SSH @@ -63,7 +65,6 @@ func NewServer(cfg *config.Config) *Server { } else { opts = append(opts, wish.WithHostKeyPath(cfg.PrivateKeyPath())) } - opts = append(opts) sh, err := wish.NewServer(opts...) if err != nil { log.Fatalln(err) @@ -82,6 +83,9 @@ func NewServer(cfg *config.Config) *Server { } s.GitServer = d } + if cfg.HTTP.Enabled { + s.HTTPServer = newHTTPServer(cfg) + } return s } @@ -97,6 +101,15 @@ func (s *Server) Start() error { return nil }) } + if s.Config.HTTP.Enabled { + errg.Go(func() error { + log.Printf("Starting HTTP server on %s:%d", s.Config.Host, s.Config.HTTP.Port) + if err := s.HTTPServer.ListenAndServe(); err != http.ErrServerClosed { + return err + } + return nil + }) + } errg.Go(func() error { log.Printf("Starting SSH server on %s:%d", s.Config.Host, s.Config.SSH.Port) if err := s.SSHServer.ListenAndServe(); err != ssh.ErrServerClosed { @@ -115,6 +128,11 @@ func (s *Server) Shutdown(ctx context.Context) error { return s.GitServer.Shutdown(ctx) }) } + if s.Config.HTTP.Enabled { + errg.Go(func() error { + return s.HTTPServer.Shutdown(ctx) + }) + } errg.Go(func() error { return s.SSHServer.Shutdown(ctx) }) @@ -132,5 +150,10 @@ func (s *Server) Close() error { return s.GitServer.Close() }) } + if s.Config.HTTP.Enabled { + errg.Go(func() error { + return s.HTTPServer.Close() + }) + } return errg.Wait() }