mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-07 06:59:59 +08:00
chore: refactor rest file server (#4851)
Signed-off-by: kevin <wanjunfeng@gmail.com>
This commit is contained in:
@@ -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.Open’s 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 doesn’t 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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user