Clean paths when looking in Storage (#19124)

* Clean paths when looking in Storage

Ensure paths are clean for minio aswell as local storage.

Use url.Path not RequestURI/EscapedPath in storageHandler.

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Apply suggestions from code review

Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
zeripath 2022-03-22 21:02:26 +00:00 committed by GitHub
parent d2c165811a
commit 3f71ab9a12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 51 deletions

View file

@ -11,7 +11,6 @@ import (
"net/http"
"os"
"path"
"path/filepath"
"strings"
"code.gitea.io/gitea/modules/context"
@ -28,6 +27,7 @@ import (
)
func storageHandler(storageSetting setting.Storage, prefix string, objStore storage.ObjectStorage) func(next http.Handler) http.Handler {
prefix = strings.Trim(prefix, "/")
funcInfo := routing.GetFuncInfo(storageHandler, prefix)
return func(next http.Handler) http.Handler {
if storageSetting.ServeDirect {
@ -37,13 +37,15 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor
return
}
if !strings.HasPrefix(req.URL.RequestURI(), "/"+prefix) {
if !strings.HasPrefix(req.URL.Path, "/"+prefix+"/") {
next.ServeHTTP(w, req)
return
}
routing.UpdateFuncInfo(req.Context(), funcInfo)
rPath := strings.TrimPrefix(req.URL.RequestURI(), "/"+prefix)
rPath := strings.TrimPrefix(req.URL.Path, "/"+prefix+"/")
rPath = path.Clean("/" + strings.ReplaceAll(rPath, "\\", "/"))[1:]
u, err := objStore.URL(rPath, path.Base(rPath))
if err != nil {
if os.IsNotExist(err) || errors.Is(err, os.ErrNotExist) {
@ -55,11 +57,12 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor
http.Error(w, fmt.Sprintf("Error whilst getting URL for %s %s", prefix, rPath), 500)
return
}
http.Redirect(
w,
req,
u.String(),
301,
http.StatusMovedPermanently,
)
})
}
@ -70,22 +73,18 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor
return
}
prefix := strings.Trim(prefix, "/")
if !strings.HasPrefix(req.URL.EscapedPath(), "/"+prefix+"/") {
if !strings.HasPrefix(req.URL.Path, "/"+prefix+"/") {
next.ServeHTTP(w, req)
return
}
routing.UpdateFuncInfo(req.Context(), funcInfo)
rPath := strings.TrimPrefix(req.URL.EscapedPath(), "/"+prefix+"/")
rPath = strings.TrimPrefix(rPath, "/")
rPath := strings.TrimPrefix(req.URL.Path, "/"+prefix+"/")
rPath = path.Clean("/" + strings.ReplaceAll(rPath, "\\", "/"))[1:]
if rPath == "" {
http.Error(w, "file not found", 404)
return
}
rPath = path.Clean("/" + filepath.ToSlash(rPath))
rPath = rPath[1:]
fi, err := objStore.Stat(rPath)
if err == nil && httpcache.HandleTimeCache(req, w, fi) {