go - 覆盖 http.FileServer 中的 Last-Modified header

标签 go http-headers last-modified

我试图覆盖 http.FileServer 设置的 Last-Modified header ,但它恢复为 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)
    })
}

最佳答案

http.FileServer() 返回的处理程序无条件地在 http.serveFile()http.serveContent() 未导出函数中设置 "Last-Modified" header :

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.FileSystem您传递给 http.FileServer() 的实现,您可以在其中报告您希望的任何最后修改的时间戳。

这需要您实现以下接口(interface):

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() 的文件信息返回的时间戳一致的自定义上次修改时间戳。查看相关问题如何做到这一点:Simples way to make a []byte into a "virtual" File object in golang?

关于go - 覆盖 http.FileServer 中的 Last-Modified header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47033156/

相关文章:

python - Django Response 总是 Chunked with text/html 无法设置 Content-Length

json - 如何使用 Go map 创建对象的 JSON 数组?

docker - 下面两个 docker 命令有什么区别?

golang 编译时(静态代码分析)检测格式化字符串和参数之间的不匹配

vb.net - 如何获取远程文件的最后修改值?

mysql - 从具有父子关系的留言板中查询最后的 n,15 个主题

excel - VBA - 如何获取 Excel 2010 目录中最后修改的文件或文件夹

arrays - 按值对 map 排序,然后将其放入GO中的另一张 map 中

java - 向 Spring ResponseEntity 添加一个新的 Header

asp.net-mvc-4 - 如何控制 MVC 4 Web API 中的 ETag header ?