duan1989643 2014-11-13 07:49
浏览 135
已采纳

如何使用http.ServeContent()处理修改的时间?

I'm trying to use ServeContent to serve files (which may be large movie files, so it will use byte ranges), but I'm not sure how to handle the modified time. If I use the following program to serve a movie, it fails if I give the actual modified time of the file as shown. I think what happens is that the first request works, but subsequent ones (of different byte ranges of the file) think it already has the file and therefore they fail and the movie doesn't play. Is there something I am doing wrong?

Note that the code works (and the movie plays properly) if I use time.Now() instead of the actual modified time of the file, but that isn't correct of course.

package main

import (
    "fmt"
    "net/http"
    "os"
    "path"
    "time"
)

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":3000", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
    filePath := "." + r.URL.Path
    file, err := os.Open(filePath)
    if err != nil {
        fmt.Printf("%s not found
", filePath)
        w.WriteHeader(http.StatusNotFound)
        fmt.Fprint(w, "<html><body style='font-size:100px'>four-oh-four</body></html>")
        return
    }
    defer file.Close()
    fileStat, err := os.Stat(filePath)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Printf("serve %s
", filePath)
    _, filename := path.Split(filePath)
    t := fileStat.ModTime()
    fmt.Printf("time %+v
", t)
    http.ServeContent(w, r, filename, t, file)
}
  • 写回答

1条回答 默认 最新

  • duanao3204 2014-11-13 11:07
    关注

    According to the documentation,

    If modtime is not the zero time, ServeContent includes it in a Last-Modified header in the response. If the request includes an If-Modified-Since header, ServeContent uses modtime to decide whether the content needs to be sent at all.

    So, depending on whether the client sends the If-Modified-Since header, this function will behave correctly or not. This seems to be the intended behaviour, and is indeed useful in normal situations to optimize the server's bandwidth.

    In your case, however, as you have to handle partial-content requests, unless the first request returns a 30X HTTP code, you have no reason to handle this mechanism for subsequent requests.

    The correct way to disable this behaviour is to pass a "zero" date to ServeContent:

    http.ServeContent(w, r, filename, time.Time{}, file)
    

    You could try to parse the request range header in order to only pass a zero date if necessary.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!