Reputation: 1
Very new to GoLang, less than 10 days. I have a http server & i need to http serve files which are inside disk. Here in default this is using "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. But seems not working.
Http Headers i worrying about are,
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
sample big fig: 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
Can help?
Upvotes: 0
Views: 2544
Reputation: 753
w.Header().Set("Accept-Ranges", "bytes")
is not required because Range will set http.ServeFile
when responding.
w.Header().Set("Content-Length", strconv.FormatInt(info.Size(), 10))
is wrong, may respond to transmission, and http.ServerFile
will set this 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. The correct method is to use http.ServeFile
to send the file directly. The ServeFile function will automatically handle the situation of Range and Cache.
Just look at the source code of net/http/fs.go
.
Upvotes: 0