chore: refactor rest file server (#4851)

Signed-off-by: kevin <wanjunfeng@gmail.com>
This commit is contained in:
Kevin Wan
2025-05-11 12:44:43 +08:00
committed by GitHub
parent 5564c43197
commit 2e91ba5811

View File

@@ -2,16 +2,16 @@ package fileserver
import (
"net/http"
pathpkg "path"
"path"
"strings"
"sync"
)
// Middleware returns a middleware that serves files from the given file system.
func Middleware(path string, fs http.FileSystem) func(http.HandlerFunc) http.HandlerFunc {
func Middleware(upath string, fs http.FileSystem) func(http.HandlerFunc) http.HandlerFunc {
fileServer := http.FileServer(fs)
pathWithoutTrailSlash := ensureNoTrailingSlash(path)
canServe := createServeChecker(path, fs)
pathWithoutTrailSlash := ensureNoTrailingSlash(upath)
canServe := createServeChecker(upath, fs)
return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
@@ -29,7 +29,7 @@ func createFileChecker(fs http.FileSystem) func(string) bool {
var lock sync.RWMutex
fileChecker := make(map[string]bool)
return func(path string) bool {
return func(upath string) bool {
// Emulate http.Dir.Opens path normalization for embed.FS.Open.
// http.FileServer redirects any request ending in "/index.html"
// to the same path without the final "index.html".
@@ -37,13 +37,14 @@ func createFileChecker(fs http.FileSystem) func(string) bool {
// http.Dir.Open uses this logic to clean the path,
// correctly handling those two cases.
// embed.FS doesnt perform this normalization, so we apply the same logic here.
path = pathpkg.Clean("/" + path)[1:]
if path == "" {
path = "."
upath = path.Clean("/" + upath)[1:]
if len(upath) == 0 {
// if the path is empty, we use "." to open the current directory
upath = "."
}
lock.RLock()
exist, ok := fileChecker[path]
exist, ok := fileChecker[upath]
lock.RUnlock()
if ok {
return exist
@@ -52,9 +53,9 @@ func createFileChecker(fs http.FileSystem) func(string) bool {
lock.Lock()
defer lock.Unlock()
file, err := fs.Open(path)
file, err := fs.Open(upath)
exist = err == nil
fileChecker[path] = exist
fileChecker[upath] = exist
if err != nil {
return false
}
@@ -64,8 +65,8 @@ func createFileChecker(fs http.FileSystem) func(string) bool {
}
}
func createServeChecker(path string, fs http.FileSystem) func(r *http.Request) bool {
pathWithTrailSlash := ensureTrailingSlash(path)
func createServeChecker(upath string, fs http.FileSystem) func(r *http.Request) bool {
pathWithTrailSlash := ensureTrailingSlash(upath)
fileChecker := createFileChecker(fs)
return func(r *http.Request) bool {
@@ -75,18 +76,18 @@ func createServeChecker(path string, fs http.FileSystem) func(r *http.Request) b
}
}
func ensureTrailingSlash(path string) string {
if strings.HasSuffix(path, "/") {
return path
func ensureTrailingSlash(upath string) string {
if strings.HasSuffix(upath, "/") {
return upath
}
return path + "/"
return upath + "/"
}
func ensureNoTrailingSlash(path string) string {
if strings.HasSuffix(path, "/") {
return path[:len(path)-1]
func ensureNoTrailingSlash(upath string) string {
if strings.HasSuffix(upath, "/") {
return upath[:len(upath)-1]
}
return path
return upath
}