1
0
Fork 0
mirror of https://git.sr.ht/~adnano/go-gemini synced 2024-05-18 20:36:04 +02:00

fs: Improve redirect behavior

This commit is contained in:
Adnan Maolood 2021-04-21 12:41:56 -04:00
parent 507773618b
commit c85759d777

29
fs.go
View File

@ -32,17 +32,19 @@ type fileServer struct {
func (fsys fileServer) ServeGemini(ctx context.Context, w ResponseWriter, r *Request) { func (fsys fileServer) ServeGemini(ctx context.Context, w ResponseWriter, r *Request) {
const indexPage = "/index.gmi" const indexPage = "/index.gmi"
url := path.Clean(r.URL.Path)
// Redirect .../index.gmi to .../ // Redirect .../index.gmi to .../
if strings.HasSuffix(r.URL.Path, indexPage) { if strings.HasSuffix(url, indexPage) {
w.WriteHeader(StatusPermanentRedirect, "./") w.WriteHeader(StatusPermanentRedirect, strings.TrimSuffix(url, "index.gmi"))
return return
} }
name := path.Clean(r.URL.Path) name := url
if name == "/" { if name == "/" {
name = "." name = "."
} else { } else {
name = strings.Trim(name, "/") name = strings.TrimPrefix(name, "/")
} }
f, err := fsys.Open(name) f, err := fsys.Open(name)
@ -59,16 +61,19 @@ func (fsys fileServer) ServeGemini(ctx context.Context, w ResponseWriter, r *Req
} }
// Redirect to canonical path // Redirect to canonical path
if len(name) != 0 { if len(r.URL.Path) != 0 {
if stat.IsDir() { if stat.IsDir() {
// Add trailing slash target := url
if name[len(name)-1] != '/' { if target != "/" {
w.WriteHeader(StatusPermanentRedirect, path.Base(name)+"/") target += "/"
}
if r.URL.Path != target {
w.WriteHeader(StatusPermanentRedirect, target)
return return
} }
} else if name[len(name)-1] == '/' { } else if r.URL.Path[len(r.URL.Path)-1] == '/' {
// Remove trailing slash // Remove trailing slash
w.WriteHeader(StatusPermanentRedirect, "../"+path.Base(name)) w.WriteHeader(StatusPermanentRedirect, url)
return return
} }
} }
@ -95,8 +100,8 @@ func (fsys fileServer) ServeGemini(ctx context.Context, w ResponseWriter, r *Req
} }
// ServeFile responds to the request with the contents of the named file // ServeFile responds to the request with the contents of the named file
// or directory. If the provided name is constructed from user input, it should // or directory. If the provided name is constructed from user input, it
// be sanitized before calling ServeFile. // should be sanitized before calling ServeFile.
func ServeFile(w ResponseWriter, fsys fs.FS, name string) { func ServeFile(w ResponseWriter, fsys fs.FS, name string) {
const indexPage = "/index.gmi" const indexPage = "/index.gmi"