diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 7713229..95bbab4 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -29,9 +29,12 @@ Hosts are defined by their hostname followed by one or more paths to serve. Paths may be defined as fixed strings or regular expressions (starting with `^`). -Paths are matched in the order they are defined. +Any path not matching a specific page, file name or file extension should end +in a trailing slash, signifying that it is a directory. Visitors are +automatically redirected when accessing a directory path without including a +trailing slash. -Fixed string paths will match with and without a trailing slash. +Paths are matched in the order they are defined. When accessing a directory the file `index.gemini` or `index.gmi` is served. @@ -223,18 +226,18 @@ hosts: root: /home/geminirocks/public_html fastcgi: unix:///var/run/php.sock - - path: /files + path: /files/ root: /home/geminirocks/files cache: 604800 # Cache for 1 week list: true # Enable directory listing - - path: ^/(help|info)$ + path: ^/(help|info)/$ root: /home/geminirocks/docs/help - - path: ^/proxy-example$ + path: /proxy-example/ proxy: gemini://localhost:1966 - - path: ^/cmd-example$ + path: /cmd-example command: uname -a cache: 0 # Do not cache - diff --git a/config.go b/config.go index d21cea6..4a75b4d 100644 --- a/config.go +++ b/config.go @@ -214,9 +214,6 @@ func readconfig(configPath string) error { if serve.Path == "" { log.Fatal("a path must be specified in each serve entry") } - if len(serve.Path) > 1 && serve.Path[len(serve.Path)-1] == '/' { - serve.Path = serve.Path[:len(serve.Path)-1] - } if serve.Path[0] == '^' { serve.r = regexp.MustCompile(serve.Path) } diff --git a/server.go b/server.go index c3e5cce..be647b6 100644 --- a/server.go +++ b/server.go @@ -133,9 +133,6 @@ func servePath(c *tls.Conn, request *url.URL, serve *pathConfig) (int, int64) { if serve.Path[0] == '/' { pathSlashes++ // Regexp does not match starting slash } - if serve.Path[0] != '^' && serve.Path[len(serve.Path)-1] != '/' { - pathSlashes++ - } } if len(requestSplit) >= pathSlashes { resolvedPath = strings.Join(requestSplit[pathSlashes:], "/") @@ -262,15 +259,27 @@ func handleRequest(c *tls.Conn, request *url.URL, requestData string) (int, int6 matchedRegexp := serve.r != nil && serve.r.Match(pathBytes) matchedPrefix := serve.r == nil && strings.HasPrefix(request.Path, serve.Path) if !matchedRegexp && !matchedPrefix { + matchedRegexp = serve.r != nil && serve.r.Match(append(pathBytes[:], byte('/'))) + matchedPrefix = serve.r == nil && strings.HasPrefix(request.Path+"/", serve.Path) + if matchedRegexp || matchedPrefix { + newRequest, err := url.Parse(request.String()) + if err != nil { + return writeStatus(c, statusBadRequest), -1, "" + } + newRequest.Path += "/" + + return writeHeader(c, statusRedirectTemporary, newRequest.String()), -1, serve.Log + } + continue } requireInput := serve.Input != "" || serve.SensitiveInput != "" if request.RawQuery == "" && requireInput { if serve.SensitiveInput != "" { - return writeHeader(c, statusSensitiveInput, serve.SensitiveInput), -1, "" + return writeHeader(c, statusSensitiveInput, serve.SensitiveInput), -1, serve.Log } - return writeHeader(c, statusInput, serve.Input), -1, "" + return writeHeader(c, statusInput, serve.Input), -1, serve.Log } if matchedRegexp || matchedPrefix {