Golang http serve file - поддержка параллельной загрузки - contentLength & accept диапазоны не работают - PullRequest
0 голосов
/ 25 апреля 2020

Очень новый для GoLang, менее 10 дней. У меня есть http-сервер, и мне нужно http-файлы, которые находятся на диске. Здесь по умолчанию используется http ". Net / http" .ServeFile (w, r, file). Моя проблема в том, что когда я загружаю эти файлы, они не поддерживают паузу / возобновление файла, а просто загружают без отображения общего размера. Я попытался добавить заголовок "Content-Length" и "Accept-Ranges" "заголовок . Но, кажется, не работает.

Заголовки Http, о которых я беспокоюсь:

  • Content-Length
  • Content-Type
  • Accept-Ranges
  • Content -Расположение (вложение)

У меня есть путь к файлу , info FileInfo , w http.ResponseWriter , r http.Request перед обслуживанием функции. Сначала я попытался добавить

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

к

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)
        }

Тогда я все еще вижу, что он загружается, не показывая общий размер, не имеет поддержки паузы / возобновления. Я пытался загрузить файлы из

образца небольшого файла: https://s2.torrentfast.net/download/Dracula.2020.S01E01.HDTV.x264-PHOENiX [TGx] / [TGx] Загружено% 20 от% 20torrentgalaxy.to% 20.txt

образец большой рис: https://s2.torrentfast.net/download/Need%20For%20Speed%20Most%20Wanted%20Black%20Edition%20repack%20Mr%20DJ/Setup-1.bin

Http Получить скриншот ссылки на заголовки ответа на запрос (образец небольшого файла)

Может помочь?

1 Ответ

0 голосов
/ 26 апреля 2020

w.Header().Set("Accept-Ranges", "bytes") не требуется, поскольку при ответе Range будет установлено значение http.ServeFile.

w.Header().Set("Content-Length", strconv.FormatInt(info.Size(), 10)) неверно, может ответить на передачу, и http.ServerFile установит этот заголовок.

Значение Content-Length означает указание длины тела, а Content-Range запишет раздел дальности передачи и информацию об общей длине. Правильный метод - использовать http.ServeFile для прямой отправки файла. Функция ServeFile автоматически обработает ситуацию Range и Cache.

Просто посмотрите на исходный код net/http/fs.go.

...