К счастью или нет, стандартное поведение http.FileServer
заключается в том, что если путь обозначает каталог без файла index.html
, список каталогов будет обслуживаться. И это не обеспечивает простой способ выключить это. Но ...
http.FileServer
работает на виртуальной файловой системе, описанной интерфейсом http.FileSystem
.
Этот интерфейс имеет единственный метод, который сообщает, как открыть файл и получить http.File
«просмотр» его:
type FileSystem interface {
Open(name string) (File, error)
}
Если вы хотите отключить список каталогов, все, что вам нужно сделать, - это предоставить собственную реализацию http.FileSystem
, которая, когда на каталог нацелен, вы просто сообщаете / возвращаете ошибку. Это все, что нужно.
Конечно, вам не нужно делать все это самостоятельно. Вы можете создать свою собственную FileSystem
, которая использует / использует http.Dir
, которая является реализацией по умолчанию, которая использует собственную файловую систему (ограниченную определенным деревом каталогов).
type myfs struct {
http.Dir
}
func (m myfs) Open(name string) (result http.File, err error) {
f, err := m.Dir.Open(name)
if err != nil {
return
}
fi, err := f.Stat()
if err != nil {
return
}
if fi.IsDir() {
// Return a response that would have been if directory would not exist:
return m.Dir.Open("does-not-exist")
}
return f, nil
}
Использование вышеуказанной пользовательской реализации:
handler := http.FileServer(myfs{http.Dir(*directory)})
http.Handle(
"/statics/",
http.StripPrefix(strings.TrimRight("/statics/", "/"), handler),
)
И это все. Попытка просмотреть http://locahost:3000/statics/
приведет к ответу по умолчанию:
404 page not found
Примечания:
Приведенная выше реализация выполняет второй Dir.Open()
вызов, чтобы вернуть ошибку, которая всегда одинакова. Чтобы «ускорить процесс», мы можем сохранить этот ответ и просто повторно использовать его:
var notFoundFile, notFoundErr = http.Dir("dummy").Open("does-not-exist")
И когда мы обнаруживаем каталог в нашем myfs.Open()
методе:
if fi.IsDir() {
// Return a response that "belogns" to opening a non-existing folder:
return notFoundFile, notFoundErr
}