简体   繁体   English

Golang http 服务文件 - 提供并行下载支持 - contentLength 和接受范围不起作用

[英]Golang http serve file - giving parallel download support - contentLength & accept ranges not working

Very new to GoLang , less than 10 days.GoLang非常陌生,不到 10 天。 I have a http server & i need to http serve files which are inside disk.我有一个 http 服务器 & 我需要 http 服务磁盘内的文件。 Here in default this is using "net/http" http.ServeFile(w, r, file).这里默认使用“net/http”http.ServeFile(w, r, file)。 My problem is when i downloading these files, they don't have file pause/resume support but just downloading without showing total size.我的问题是当我下载这些文件时,它们没有文件暂停/恢复支持,只是下载而不显示总大小。 I tried adding "Content-Length" header & "Accept-Ranges" header .我尝试添加"Content-Length" header & "Accept-Ranges" header But seems not working.但似乎不起作用。

Http Headers i worrying about are, Http 我担心的标题是,

  • Content-Length内容长度
  • Content-Type内容类型
  • Accept-Ranges接受范围
  • Content-Disposition (attachment)内容处置(附件)

I have path to file , info FileInfo , w http.ResponseWriter , r http.Request before serving function.First I tried adding I have path to file , info FileInfo , w http.ResponseWriter , r http.Request before serving function.First I tried adding

w.Header().Set("Accept-Ranges", "bytes")
if w.Header().Get("Content-Encoding") == "" {
     w.Header().Set("Content-Length", strconv.FormatInt(info.Size(), 10))
}

to

func (s *Server) serveFiles(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.URL.Path, "/download/") {
    url := strings.TrimPrefix(r.URL.Path, "/download/")
    //dldir is absolute
    dldir := s.state.Config.DownloadDirectory
    file := filepath.Join(dldir, url)
    //only allow fetches/deletes inside the dl dir
    if !strings.HasPrefix(file, dldir) || dldir == file {
        http.Error(w, "Nice try\n"+dldir+"\n"+file, http.StatusBadRequest)
        return
    }
    info, err := os.Stat(file)
    if err != nil {
        http.Error(w, "File stat error: "+err.Error(), http.StatusBadRequest)
        return
    }
    switch r.Method {
    case "GET":
        if info.IsDir() {
            w.Header().Set("Content-Type", "application/zip")
            w.WriteHeader(200)
            //write .zip archive directly into response
            a := archive.NewZipWriter(w)
            a.AddDir(file)
            a.Close()
        } else {
            w.Header().Set("Accept-Ranges", "bytes")
            if w.Header().Get("Content-Encoding") == "" {
                w.Header().Set("Content-Length", strconv.FormatInt(info.Size(), 10))
            }
            http.ServeFile(w, r, file)
        }

Then i can still see it is downloading without showing total size, doesn't have pause/resume support.然后我仍然可以看到它正在下载而不显示总大小,没有暂停/恢复支持。 i tried to download files from我试图从

sample small file: https://s2.torrentfast.net/download/Dracula.2020.S01E01.HDTV.x264-PHOENiX[TGx]/[TGx]Downloaded%20from%20torrentgalaxy.to%20.txt示例小文件: https://s2.torrentfast.net/download/Dracula.2020.S01E01.HDTV.x264-PHOENiX[TGx]/[TGx]Downloaded%20from%20torrentgalaxy.to%20.txt

sample big fig: https://s2.torrentfast.net/download/Need%20For%20Speed%20Most%20Wanted%20Black%20Edition%20repack%20Mr%20DJ/Setup-1.bin示例大图: https://s2.torrentfast.net/download/Need%20For%20Speed%20Most%20Wanted%20Black%20Edition%20repack%20Mr%20DJ/Setup-1.bin

Http Get request response headers(sample small file) screenshot link Http 获取请求响应头(示例小文件)截图链接

Can help?可以帮忙?

w.Header().Set("Accept-Ranges", "bytes") is not required because Range will set http.ServeFile when responding. w.Header().Set("Accept-Ranges", "bytes")不是必需的,因为 Range 会在响应时设置http.ServeFile

w.Header().Set("Content-Length", strconv.FormatInt(info.Size(), 10)) is wrong, may respond to transmission, and http.ServerFile will set this header. w.Header().Set("Content-Length", strconv.FormatInt(info.Size(), 10))错误,可能会响应传输, http.ServerFile会设置这个 header。

The meaning of Content-Length is to specify the length of the body, and Content-Range will record the section of the transmission range and the total length information. Content-Length的含义是指定body的长度, Content-Range会记录传输范围的部分和总长度信息。 The correct method is to use http.ServeFile to send the file directly.正确的方法是使用http.ServeFile直接发送文件。 The ServeFile function will automatically handle the situation of Range and Cache. ServeFile function 会自动处理 Range 和 Cache 的情况。

Just look at the source code of net/http/fs.go .看看net/http/fs.go的源码就知道了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM