diff --git a/config.go b/config.go index ded2805..6acdcb1 100644 --- a/config.go +++ b/config.go @@ -8,15 +8,16 @@ import ( ) type config struct { - Server *configServer `mapstructure:"server"` - Db *configDb `mapstructure:"database"` - Cache *configCache `mapstructure:"cache"` - DefaultBlog string `mapstructure:"defaultblog"` - Blogs map[string]*configBlog `mapstructure:"blogs"` - User *configUser `mapstructure:"user"` - Hooks *configHooks `mapstructure:"hooks"` - Hugo *configHugo `mapstructure:"hugo"` - Micropub *configMicropub `mapstructure:"micropub"` + Server *configServer `mapstructure:"server"` + Db *configDb `mapstructure:"database"` + Cache *configCache `mapstructure:"cache"` + DefaultBlog string `mapstructure:"defaultblog"` + Blogs map[string]*configBlog `mapstructure:"blogs"` + User *configUser `mapstructure:"user"` + Hooks *configHooks `mapstructure:"hooks"` + Hugo *configHugo `mapstructure:"hugo"` + Micropub *configMicropub `mapstructure:"micropub"` + PathRedirects []*configRegexRedirect `mapstructure:"pathRedirects"` } type configServer struct { @@ -135,6 +136,11 @@ type configMicropubMedia struct { TinifyKey string `mapstructure:"tinifyKey"` } +type configRegexRedirect struct { + From string `mapstructure:"from"` + To string `mapstructure:"to"` +} + var appConfig = &config{} func initConfig() error { diff --git a/example-config.yaml b/example-config.yaml index 9ac183d..159ff06 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -60,4 +60,11 @@ micropub: bookmarkParam: link audioParam: audio photoParam: images - photoDescriptionParam: imagealts \ No newline at end of file + photoDescriptionParam: imagealts +pathRedirects: + - from: "\\/index\\.xml" + to: ".rss" + - from: "\\/feed\\.json" + to: ".json" + - from: "\\/(feed|rss)\\/?$" + to: ".rss" \ No newline at end of file diff --git a/http.go b/http.go index 8c653f8..db63a26 100644 --- a/http.go +++ b/http.go @@ -136,7 +136,7 @@ func buildHandler() (http.Handler, error) { r.Get(path, serveAsset) } - paginationPath := "/page/{page}" + paginationPath := "/page/{page:[0-9-]+}" feedPath := ".{feed:rss|json|atom}" for blog, blogConfig := range appConfig.Blogs { @@ -199,7 +199,8 @@ func buildHandler() (http.Handler, error) { // Sitemap r.With(cacheMiddleware).Get(sitemapPath, serveSitemap) - r.With(minifier.Middleware).NotFound(serve404) + // Check redirects, then serve 404 + r.With(checkRegexRedirects, minifier.Middleware).NotFound(serve404) return r, nil } diff --git a/main.go b/main.go index 72fe4ef..2f42f9a 100644 --- a/main.go +++ b/main.go @@ -45,6 +45,11 @@ func main() { log.Fatal(err) return } + err = initRedirects() + if err != nil { + log.Fatal(err) + return + } // Prepare graceful shutdown quit := make(chan os.Signal, 1) diff --git a/regexRedirects.go b/regexRedirects.go new file mode 100644 index 0000000..39b1989 --- /dev/null +++ b/regexRedirects.go @@ -0,0 +1,42 @@ +package main + +import ( + "net/http" + "regexp" +) + +var regexRedirects []*regexRedirect + +type regexRedirect struct { + From *regexp.Regexp + To string +} + +func initRedirects() error { + for _, cr := range appConfig.PathRedirects { + re, err := regexp.Compile(cr.From) + if err != nil { + return err + } + regexRedirects = append(regexRedirects, ®exRedirect{ + From: re, + To: cr.To, + }) + } + return nil +} + +func checkRegexRedirects(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + oldPath := r.URL.Path + for _, re := range regexRedirects { + newPath := re.From.ReplaceAllString(oldPath, re.To) + if oldPath != newPath { + r.URL.Path = newPath + http.Redirect(w, r, r.URL.String(), http.StatusFound) + return + } + } + next.ServeHTTP(w, r) + }) +}