Вот основной код, который нам нужно посмотреть, который исходит из источника относительно http.FileServer
:
func (f *fileHandler) ServeHTTP(w ResponseWriter, r *Request) {
upath := r.URL.Path
if !strings.HasPrefix(upath, "/") {
upath = "/" + upath
r.URL.Path = upath
}
serveFile(w, r, f.root, path.Clean(upath), true)
}
// name is '/'-separated, not filepath.Separator.
func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirect bool) {
const indexPage = "/index.html"
// redirect .../index.html to .../
// can't use Redirect() because that would make the path absolute,
// which would be a problem running under StripPrefix
if strings.HasSuffix(r.URL.Path, indexPage) {
localRedirect(w, r, "./")
return
}
f, err := fs.Open(name)
if err != nil {
msg, code := toHTTPError(err)
Error(w, msg, code)
return
}
defer f.Close()
...
}
В методе ServeHTTP
вы увидите вызов неэкспортированной функции.
serveFile(w, r, f.root, path.Clean(upath), true)
, где upath
- путь URL запроса, который гарантированно начинается с "/".
В serveFile
, вызывается fs.Open(name)
, где fs
FileSystem
вы указали, а name
- аргумент, который мы передали как path.Clean(upath)
.Обратите внимание, что path.Clean
уже вызывается, поэтому вам не нужно вызывать его в вашем методе prepare
.
Вывод здесь заключается в том, что вы сохраняете свои "имена файлов" без предшествующего "/", что означает, что они находятся в корне файловой системы.
Вы можете исправить это двумя различными способами.
1.
ASSETS["/index.html"] = LoadAsset("index.html", HTML, ASSETS)
ASSETS["/style.css"] = LoadAsset("style.css", CSS, ASSETS)
2.
func (fs StaticFS) Open(name string) (http.File, error) {
if strings.HasPrefix(name, "/") {
name = name[1:]
}
f, err := fs.prepare(name)
if err != nil {
return nil, err
}
return f.File()
}