Open Tnze opened 3 years ago
Hi!
Fast solution: rename your index.html
to index.htm
, use c.FileFromFS("www/index.htm", http.FS(static))
and all will works.
Problem in net/http FileServer https://github.com/golang/go/blob/a7e16abb22f1b249d2691b32a5d20206282898f2/src/net/http/fs.go#L587 if in folder we found index.html
, then redirect to /
Using c.FileFromFS("www/", http.FS(static))
also work well.
Hi! Fast solution: rename your
index.html
toindex.htm
, usec.FileFromFS("www/index.htm", http.FS(static))
and all will works.Problem in net/http FileServer https://github.com/golang/go/blob/a7e16abb22f1b249d2691b32a5d20206282898f2/src/net/http/fs.go#L587 if in folder we found
index.html
, then redirect to/
Hard-coding values like this is very bad. Two years later and hasn't been fixed.
use r.StaticFileFS("/", "./index.html", http.FS(staticFs))
like r.StaticFileFS("/", "./", http.FS(staticFs))
work fine
The reason:
c.FileFromFS
wraps the function http.FileServer(fs).ServeHTTP(...)
func (c *Context) FileFromFS(filepath string, fs http.FileSystem) {
defer func(old string) {
c.Request.URL.Path = old
}(c.Request.URL.Path)
c.Request.URL.Path = filepath
http.FileServer(fs).ServeHTTP(c.Writer, c.Request)
}
And http.FileServer
function has a special case:
// ...
// As a special case, the returned file server redirects any request
// ending in "/index.html" to the same path, without the final
// "index.html".
// ...
func FileServer(root FileSystem) Handler {
return &fileHandler{root}
}
As you can see, the implementation of c.FileFromFS
is just assign filepath
to http.Request,URL.Path
and then calls serverHttp
, ServeHTTP
calls serveFile
. If you serve a path ends with index.html
, FileFromFS
will automatically redirect to "./"
// 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
}
//...
In your case,
./
will let browser redirect to /
/
serves index.html
file by gin c.FileFromFS
./
/
By the way, serveFile supports reading directory by reading index.html in this directory:
// ...
if d.IsDir() {
url := r.URL.Path
// redirect if the directory name doesn't end in a slash
if url == "" || url[len(url)-1] != '/' {
localRedirect(w, r, path.Base(url)+"/")
return
}
// use contents of index.html for directory, if present
index := strings.TrimSuffix(name, "/") + indexPage //indexPage is "/index.html"
ff, err := fs.Open(index)
if err == nil {
defer ff.Close()
dd, err := ff.Stat()
if err == nil {
d = dd
f = ff
}
}
}
// ...
so @honmaple 's comment is good and easy.
Description
It's not possible to serve any static file named
index.html
in a FileSystem.How to reproduce
Expectations
Actual result
Infinite 301 redirection
Environment