我正在尝试覆盖由Last-Modified
设置的http.FileServer
- 标头,但它会恢复到我正在尝试投放的文件的Last-Modified
- 时间:
var myTime time.Time
func main() {
myTime = time.Now()
fs := http.StripPrefix("/folder/", SetCacheHeader(http.FileServer(http.Dir("/folder/"))))
http.Handle("/folder/", fs)
http.ListenAndServe(":80", nil)
}
我的SetCacheHeader
- 处理程序:
func SetCacheHeader(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Last-Modified", myTime.Format(http.TimeFormat))
h.ServeHTTP(w, r)
})
}
答案 0 :(得分:6)
http.FileServer()
返回的处理程序无条件地在"Last-Modified"
和http.serveFile()
未导出的函数中设置http.serveContent()
标头:
func serveFile(w ResponseWriter, r *Request, fs FileSystem,
name string, redirect bool) {
// ...
f, err := fs.Open(name)
// ...
d, err := f.Stat()
// ...
// serveContent will check modification time
sizeFunc := func() (int64, error) { return d.Size(), nil }
serveContent(w, r, d.Name(), d.ModTime(), sizeFunc, f)
}
func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time,
sizeFunc func() (int64, error), content io.ReadSeeker) {
setLastModified(w, modtime)
// ...
}
func setLastModified(w ResponseWriter, modtime time.Time) {
if !isZeroTime(modtime) {
w.Header().Set("Last-Modified", modtime.UTC().Format(TimeFormat))
}
}
因此,在调用文件服务器处理程序之前设置的内容将被覆盖。你无法对此做任何事情。
如果您需要使用自定义上次修改时间来提供文件内容,可以使用http.ServeContent()
:
func ServeContent(w ResponseWriter, req *Request, name string,
modtime time.Time, content io.ReadSeeker)
您可以通过上次修改时间来使用,但当然您会丢失http.FileServer()
提供的所有便捷功能。
如果您想继续使用http.FileServer()
,另一种选择是不使用http.Dir
类型,而是创建您传递给http.FileServer()
的自己的http.FileSystem
实施,您可以在其中报告您希望的任何上次修改时间戳。
这需要您实现以下界面:
type FileSystem interface {
Open(name string) (File, error)
}
因此,您需要一个按名称打开文件的方法,并返回一个实现http.File
的值,即:
type File interface {
io.Closer
io.Reader
io.Seeker
Readdir(count int) ([]os.FileInfo, error)
Stat() (os.FileInfo, error)
}
您返回的值(实现http.File
)可以有Stat() (os.FileInfo, error)
方法实现,其os.FileInfo
返回值包含您选择的上次修改时间。请注意,您还应该实现Readdir()
方法,以返回与Stat()
的fileinfo返回的时间戳一致的自定义上次修改时间戳。请参阅相关问题如何执行此操作:Simples way to make a []byte into a "virtual" File object in golang?