mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-14 18:30:02 +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 (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
pathpkg "path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Middleware returns a middleware that serves files from the given file system.
|
// 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)
|
fileServer := http.FileServer(fs)
|
||||||
pathWithoutTrailSlash := ensureNoTrailingSlash(path)
|
pathWithoutTrailSlash := ensureNoTrailingSlash(upath)
|
||||||
canServe := createServeChecker(path, fs)
|
canServe := createServeChecker(upath, fs)
|
||||||
|
|
||||||
return func(next http.HandlerFunc) http.HandlerFunc {
|
return func(next http.HandlerFunc) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -29,7 +29,7 @@ func createFileChecker(fs http.FileSystem) func(string) bool {
|
|||||||
var lock sync.RWMutex
|
var lock sync.RWMutex
|
||||||
fileChecker := make(map[string]bool)
|
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.
|
// Emulate http.Dir.Open’s path normalization for embed.FS.Open.
|
||||||
// http.FileServer redirects any request ending in "/index.html"
|
// http.FileServer redirects any request ending in "/index.html"
|
||||||
// to the same path without the final "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,
|
// http.Dir.Open uses this logic to clean the path,
|
||||||
// correctly handling those two cases.
|
// correctly handling those two cases.
|
||||||
// embed.FS doesn’t perform this normalization, so we apply the same logic here.
|
// embed.FS doesn’t perform this normalization, so we apply the same logic here.
|
||||||
path = pathpkg.Clean("/" + path)[1:]
|
upath = path.Clean("/" + upath)[1:]
|
||||||
if path == "" {
|
if len(upath) == 0 {
|
||||||
path = "."
|
// if the path is empty, we use "." to open the current directory
|
||||||
|
upath = "."
|
||||||
}
|
}
|
||||||
|
|
||||||
lock.RLock()
|
lock.RLock()
|
||||||
exist, ok := fileChecker[path]
|
exist, ok := fileChecker[upath]
|
||||||
lock.RUnlock()
|
lock.RUnlock()
|
||||||
if ok {
|
if ok {
|
||||||
return exist
|
return exist
|
||||||
@@ -52,9 +53,9 @@ func createFileChecker(fs http.FileSystem) func(string) bool {
|
|||||||
lock.Lock()
|
lock.Lock()
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
|
|
||||||
file, err := fs.Open(path)
|
file, err := fs.Open(upath)
|
||||||
exist = err == nil
|
exist = err == nil
|
||||||
fileChecker[path] = exist
|
fileChecker[upath] = exist
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
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 {
|
func createServeChecker(upath string, fs http.FileSystem) func(r *http.Request) bool {
|
||||||
pathWithTrailSlash := ensureTrailingSlash(path)
|
pathWithTrailSlash := ensureTrailingSlash(upath)
|
||||||
fileChecker := createFileChecker(fs)
|
fileChecker := createFileChecker(fs)
|
||||||
|
|
||||||
return func(r *http.Request) bool {
|
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 {
|
func ensureTrailingSlash(upath string) string {
|
||||||
if strings.HasSuffix(path, "/") {
|
if strings.HasSuffix(upath, "/") {
|
||||||
return path
|
return upath
|
||||||
}
|
}
|
||||||
|
|
||||||
return path + "/"
|
return upath + "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
func ensureNoTrailingSlash(path string) string {
|
func ensureNoTrailingSlash(upath string) string {
|
||||||
if strings.HasSuffix(path, "/") {
|
if strings.HasSuffix(upath, "/") {
|
||||||
return path[:len(path)-1]
|
return upath[:len(upath)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
return path
|
return upath
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user