engine/canonpath.go
Rama main · réplica de lectura del repositorio original.
package engine
// Middleware that runs before the mux, for all served handlers
import (
"net/http"
"strings"
"github.com/xyproto/algernon/utils"
"github.com/xyproto/sheepcounter"
)
// canonicalPathMiddleware canonicalizes the request path before the mux, the
// permission system and the filename lookup gets to see it, so that all three
// agree on what the path is.
func canonicalPathMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
if strings.ContainsAny(req.URL.Path, "\x00\r\n") {
http.Error(w, "Bad Request", http.StatusBadRequest)
return
}
if cleaned := utils.CanonicalURLPath(req.URL.Path); cleaned != req.URL.Path {
req.URL.Path = cleaned
// Let EscapedPath re-derive the escaped form
req.URL.RawPath = ""
}
next.ServeHTTP(w, req)
})
}
// permissionMiddleware rejects requests that the permission system does not
// allow. It wraps the entire mux, so that routes registered outside of
// RegisterHandlers are guarded as well.
func (ac *Config) permissionMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// The permission system requires a database backend, so perm can be nil
if ac.perm != nil && ac.perm.Rejected(w, req) {
// Prepare to count bytes written
sc := sheepcounter.New(w)
// Get and call the Permission Denied function
ac.perm.DenyFunction()(sc, req)
// Log the response
ac.LogAccess(req, http.StatusForbidden, sc.Counter())
// Reject the request by not calling the next handler
return
}
next.ServeHTTP(w, req)
})
}