init
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
package site
|
||||
|
||||
import "strings"
|
||||
|
||||
// splitTilde splits a site URL path into its project and the rest.
|
||||
//
|
||||
// "/~proj" -> ("proj", "", true)
|
||||
// "/~proj/" -> ("proj", "/", true)
|
||||
// "/~proj/a/b" -> ("proj", "/a/b", true)
|
||||
// "/", "/x", "/~" -> ("", "", false)
|
||||
//
|
||||
// The remainder keeps its leading slash, because its absence is what
|
||||
// distinguishes "/~proj" — which has to be redirected before relative links
|
||||
// inside the page can resolve — from "/~proj/".
|
||||
//
|
||||
// This is hand-parsed rather than expressed as a ServeMux pattern because
|
||||
// net/http rejects "/~{project}/{path...}": its wildcards must start a path
|
||||
// segment. Registering "/" instead also keeps the mux's built-in ".." and "//"
|
||||
// redirects, though those are a convenience and not a defence — a
|
||||
// percent-encoded traversal arrives here already decoded and unredirected, so
|
||||
// Resolve does its own normalisation.
|
||||
func splitTilde(urlPath string) (project, rest string, ok bool) {
|
||||
if !strings.HasPrefix(urlPath, "/~") {
|
||||
return "", "", false
|
||||
}
|
||||
rest = urlPath[len("/~"):]
|
||||
if i := strings.IndexByte(rest, '/'); i >= 0 {
|
||||
project, rest = rest[:i], rest[i:]
|
||||
} else {
|
||||
project, rest = rest, ""
|
||||
}
|
||||
if project == "" {
|
||||
return "", "", false
|
||||
}
|
||||
return project, rest, true
|
||||
}
|
||||
Reference in New Issue
Block a user