about summary refs log tree commit diff stats
path: root/internal/server/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/server/server.go')
-rw-r--r--internal/server/server.go80
1 files changed, 44 insertions, 36 deletions
diff --git a/internal/server/server.go b/internal/server/server.go
index 8523bc9..269ed9e 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -8,6 +8,7 @@ import (
 	"net/url"
 	"os"
 	"path/filepath"
+	"regexp"
 	"slices"
 	"strconv"
 	"strings"
@@ -46,10 +47,9 @@ type Config struct {
 
 type Server struct {
 	*http.Server
-	redirectServer *http.Server
-	runtimeConfig  *Config
-	config         *cfg.Config
-	log            *log.Logger
+	runtimeConfig *Config
+	config        *cfg.Config
+	log           *log.Logger
 }
 
 func applyDevModeOverrides(config *cfg.Config, runtimeConfig *Config) {
@@ -75,7 +75,6 @@ func applyDevModeOverrides(config *cfg.Config, runtimeConfig *Config) {
 }
 
 func updateCSPHashes(config *cfg.Config, r *builder.Result) {
-	clear(config.CSP.StyleSrc)
 	for i, h := range r.Hashes {
 		config.CSP.StyleSrc[i] = fmt.Sprintf("'%s'", h)
 	}
@@ -110,20 +109,24 @@ func New(runtimeConfig *Config, log *log.Logger) (*Server, error) {
 		if err != nil {
 			return nil, err
 		}
-		_, err = vcs.CloneOrUpdate(vcsConfig, log.Named("vcs"))
-		if err != nil {
-			return nil, err
-		}
-		err = os.Chdir(runtimeConfig.Root)
-		if err != nil {
-			return nil, err
-		}
+		if vcsConfig.LocalPath != "" {
+			_, err = vcs.CloneOrUpdate(vcsConfig, log.Named("vcs"))
+			if err != nil {
+				return nil, err
+			}
+			err = os.Chdir(runtimeConfig.Root)
+			if err != nil {
+				return nil, err
+			}
 
-		builderConfig.Source = vcsConfig.LocalPath
+			builderConfig.Source = vcsConfig.LocalPath
 
-		publicDir := filepath.Join(runtimeConfig.Root, "public")
-		builderConfig.Destination = publicDir
-		runtimeConfig.Root = publicDir
+			publicDir := filepath.Join(runtimeConfig.Root, "public")
+			builderConfig.Destination = publicDir
+			runtimeConfig.Root = publicDir
+		} else {
+			log.Warn("in production mode without VCS configuration")
+		}
 	}
 
 	config, err := cfg.GetConfig(builderConfig.Source, log.Named("config"))
@@ -180,24 +183,36 @@ func New(runtimeConfig *Config, log *log.Logger) (*Server, error) {
 		return nil, errors.Wrap(err, "could not create website mux")
 	}
 
-	rMux := http.NewServeMux()
-	rMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-		path, _ := website.CanonicalisePath(r.URL.Path)
-		newURL := config.BaseURL.JoinPath(path)
-		http.Redirect(w, r, newURL.String(), 301)
-	})
 	if runtimeConfig.Redirect {
+		re := regexp.MustCompile(
+			"^(.*)\\." + strings.ReplaceAll(config.WildcardDomain, ".", `\.`) + "$",
+		)
+		replace := "${1}." + config.Domains[0]
 		loggingMux.Handle(config.BaseURL.Hostname()+"/", mux)
-		loggingMux.Handle("/", rMux)
+		loggingMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+			if slices.Contains(config.Domains, r.Host) {
+				path, _ := website.CanonicalisePath(r.URL.Path)
+				newURL := config.BaseURL.JoinPath(path)
+				http.Redirect(w, r, newURL.String(), http.StatusMovedPermanently)
+			} else {
+				url := config.BaseURL
+				url.Host = re.ReplaceAllString(r.Host, replace)
+				http.Redirect(w, r, url.String(), http.StatusTemporaryRedirect)
+			}
+		})
 	} else {
 		loggingMux.Handle("/", mux)
 	}
 
-	top.Handle("/",
-		serverHeaderHandler(
-			wrapHandlerWithLogging(loggingMux, log),
-		),
-	)
+	if runtimeConfig.Development {
+		top.Handle("/",
+			serverHeaderHandler(
+				wrapHandlerWithLogging(loggingMux, log),
+			),
+		)
+	} else {
+		top.Handle("/", serverHeaderHandler(loggingMux))
+	}
 
 	top.HandleFunc("/health", func(w http.ResponseWriter, _ *http.Request) {
 		w.WriteHeader(http.StatusNoContent)
@@ -211,13 +226,6 @@ func New(runtimeConfig *Config, log *log.Logger) (*Server, error) {
 			IdleTimeout:       10 * time.Minute,
 			Handler:           top,
 		},
-		redirectServer: &http.Server{
-			ReadHeaderTimeout: 10 * time.Second,
-			ReadTimeout:       1 * time.Minute,
-			WriteTimeout:      2 * time.Minute,
-			IdleTimeout:       10 * time.Minute,
-			Handler:           rMux,
-		},
 		log:           log,
 		config:        config,
 		runtimeConfig: runtimeConfig,