about summary refs log tree commit diff stats
path: root/cmd/server/main.go
diff options
context:
space:
mode:
authorAlan Pearce2025-01-30 22:16:09 +0100
committerAlan Pearce2025-01-30 22:16:09 +0100
commit99f8047ef20a64f948ac2b703c81eb49bed091c0 (patch)
treea0365a7b2e477467a91bef247db09624028e1807 /cmd/server/main.go
parent4566db657dab6af43f8fce814cd0e42cbcc788bf (diff)
downloadwebsite-sqlite.tar.lz
website-sqlite.tar.zst
website-sqlite.zip
re-organise everything sqlite
Diffstat (limited to 'cmd/server/main.go')
-rw-r--r--cmd/server/main.go91
1 files changed, 85 insertions, 6 deletions
diff --git a/cmd/server/main.go b/cmd/server/main.go
index 8d8d4d4..fbb2318 100644
--- a/cmd/server/main.go
+++ b/cmd/server/main.go
@@ -3,19 +3,39 @@ package main
 import (
 	"context"
 	"fmt"
+	"net"
+	"net/url"
 	"os"
 	"os/signal"
+	"slices"
+	"strconv"
+	"strings"
 
+	"go.alanpearce.eu/website/internal/config"
 	"go.alanpearce.eu/website/internal/server"
+	"go.alanpearce.eu/website/internal/website"
 	"go.alanpearce.eu/x/log"
 
 	"github.com/ardanlabs/conf/v3"
 	"gitlab.com/tozd/go/errors"
 )
 
+type Options struct {
+	Development    bool   `conf:"default:false,flag:dev"`
+	DBPath         string `conf:"default:site.db"`
+	Redirect       bool   `conf:"default:true"`
+	Port           int    `conf:"default:8080,short:p"`
+	TLS            bool   `conf:"default:false"`
+	TLSPort        int    `conf:"default:8443"`
+	ListenAddress  string `conf:"default:localhost"`
+	Domains        string `conf:"default:localhost"`
+	ACMEIssuer     string
+	ACMEIssuerCert string
+}
+
 func main() {
-	runtimeConfig := server.Config{}
-	help, err := conf.Parse("", &runtimeConfig)
+	options := &Options{}
+	help, err := conf.Parse("", options)
 	if err != nil {
 		if errors.Is(err, conf.ErrHelpWanted) {
 			fmt.Println(help)
@@ -23,19 +43,63 @@ func main() {
 		}
 		panic("parsing runtime configuration" + err.Error())
 	}
-	log := log.Configure(!runtimeConfig.Development)
+	log := log.Configure(!options.Development)
+
+	cfg, err := config.GetConfig(".", log.Named("config"))
+	if err != nil {
+		log.Error("error reading configuration file", "error", err)
+	}
 
-	if runtimeConfig.Development {
-		runtimeConfig.DBPath = ":memory:"
+	// Domains?
+	webOpts := &website.Options{
+		DBPath:      options.DBPath,
+		Redirect:    options.Redirect,
+		Development: options.Development,
+		Config:      cfg,
 	}
 
-	sv, err := server.New(&runtimeConfig, log)
+	serverOpts := &server.Options{
+		Development:    options.Development,
+		ListenAddress:  options.ListenAddress,
+		Port:           options.Port,
+		TLS:            options.TLS,
+		TLSPort:        options.TLSPort,
+		ACMEIssuer:     options.ACMEIssuer,
+		ACMEIssuerCert: options.ACMEIssuerCert,
+		Config:         cfg,
+	}
+
+	if options.Development {
+		webOpts.DBPath = ":memory:"
+		cfg.CSP.ScriptSrc = slices.Insert(cfg.CSP.ScriptSrc, 0, "'unsafe-inline'")
+		cfg.CSP.ConnectSrc = slices.Insert(cfg.CSP.ConnectSrc, 0, "'self'")
+		if options.Domains != "" {
+			cfg.Domains = strings.Split(options.Domains, ",")
+		} else {
+			cfg.Domains = []string{options.ListenAddress}
+		}
+		cfg.BaseURL = mkBaseURL(options, cfg)
+	}
+
+	sv, err := server.New(serverOpts, log.Named("server"))
 	if err != nil {
 		log.Error("could not create server", "error", err)
 
 		return
 	}
 
+	website, err := website.New(webOpts, log.Named("website"))
+	if err != nil {
+		log.Error("could not initialise website", "error", err)
+
+		return
+	}
+
+	sv.HostApp(website.App)
+	if options.Redirect {
+		sv.HostFallbackApp(website.MakeRedirectorApp())
+	}
+
 	ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
 	defer cancel()
 
@@ -52,3 +116,18 @@ func main() {
 	<-sv.Stop()
 	log.Debug("done")
 }
+
+func mkBaseURL(options *Options, cfg *config.Config) config.URL {
+	scheme := "http"
+	port := options.Port
+	if options.TLS {
+		scheme = "https"
+		port = options.TLSPort
+	}
+	return config.URL{
+		URL: &url.URL{
+			Scheme: scheme,
+			Host:   net.JoinHostPort(cfg.Domains[0], strconv.Itoa(port)),
+		},
+	}
+}