shithub: hugo

Download patch

ref: 5e2a547cb594b31ecb0f089b08db2e15c6dc381a
parent: ee090c0940cdbf636e3a55a40b41612d92b9c62d
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Mon Oct 5 13:56:28 EDT 2020

Add force flag to server redirects config

Fixes #7778

--- a/commands/server.go
+++ b/commands/server.go
@@ -376,19 +376,38 @@
 			}
 
 			if redirect := f.c.serverConfig.MatchRedirect(requestURI); !redirect.IsZero() {
+				doRedirect := true
 				// This matches Netlify's behaviour and is needed for SPA behaviour.
 				// See https://docs.netlify.com/routing/redirects/rewrites-proxies/
-				if redirect.Status == 200 {
-					if r2 := f.rewriteRequest(r, strings.TrimPrefix(redirect.To, u.Path)); r2 != nil {
-						requestURI = redirect.To
-						r = r2
+				if !redirect.Force {
+					path := filepath.Clean(strings.TrimPrefix(requestURI, u.Path))
+					fi, err := f.c.hugo().BaseFs.PublishFs.Stat(path)
+					if err == nil {
+						if fi.IsDir() {
+							// There will be overlapping directories, so we
+							// need to check for a file.
+							_, err = f.c.hugo().BaseFs.PublishFs.Stat(filepath.Join(path, "index.html"))
+							doRedirect = err != nil
+						} else {
+							doRedirect = false
+						}
+
 					}
-				} else {
-					w.Header().Set("Content-Type", "")
-					http.Redirect(w, r, redirect.To, redirect.Status)
-					return
 				}
 
+				if doRedirect {
+					if redirect.Status == 200 {
+						if r2 := f.rewriteRequest(r, strings.TrimPrefix(redirect.To, u.Path)); r2 != nil {
+							requestURI = redirect.To
+							r = r2
+						}
+					} else {
+						w.Header().Set("Content-Type", "")
+						http.Redirect(w, r, redirect.To, redirect.Status)
+						return
+					}
+				}
+
 			}
 
 			if f.c.fastRenderMode && f.c.buildErr == nil {
@@ -416,7 +435,6 @@
 
 	fileserver := decorate(http.FileServer(fs))
 	mu := http.NewServeMux()
-
 	if u.Path == "" || u.Path == "/" {
 		mu.Handle("/", fileserver)
 	} else {
--- a/config/commonConfig.go
+++ b/config/commonConfig.go
@@ -184,6 +184,7 @@
 	From   string
 	To     string
 	Status int
+	Force  bool
 }
 
 func (r Redirect) IsZero() bool {
--- a/docs/content/en/getting-started/configuration.md
+++ b/docs/content/en/getting-started/configuration.md
@@ -360,10 +360,10 @@
 from = "/myspa/**"
 to = "/myspa/"
 status = 200
+force = false
 {{< /code-toggle >}}
 
-
-
+{{< new-in "0.76.0" >}} Setting `force=true` will make a redirect even if there is existing content in the path. Note that before Hugo 0.76  `force` was the default behaviour, but this is inline with how Netlify does it.
 
 ## Configure Title Case