如何使用 Go 限制下载速度?

我目前正在用 Go 开发一个下载服务器。我需要将用户的下载速度限制在 100KB/s。


这是我的代码:


func serveFile(w http.ResponseWriter, r *http.Request) {

    fileID := r.URL.Query().Get("fileID")

    if len(fileID) != 0 {

        w.Header().Set("Content-Disposition", "attachment; filename=filename.txt")

        w.Header().Set("Content-Type", r.Header.Get("Content-Type"))

        w.Header().Set("Content-Length", r.Header.Get("Content-Length"))


        file, err := os.Open(fmt.Sprintf("../../bin/files/test.txt"))

        defer file.Close()

        if err != nil {

            http.NotFound(w, r)

            return

        }

        io.Copy(w, file)

    } else {

        io.WriteString(w, "Invalid request.")

    }

}

然后我在github上找到了一个包,我的代码变成了如下:


func serveFile(w http.ResponseWriter, r *http.Request) {

    fileID := r.URL.Query().Get("fileID")

    if len(fileID) != 0 {

        w.Header().Set("Content-Disposition", "attachment; filename=Wiki.png")

        w.Header().Set("Content-Type", r.Header.Get("Content-Type"))

        w.Header().Set("Content-Length", r.Header.Get("Content-Length"))


        file, err := os.Open(fmt.Sprintf("../../bin/files/test.txt"))

        defer file.Close()

        if err != nil {

            http.NotFound(w, r)

            return

        }

        bucket := ratelimit.NewBucketWithRate(100*1024, 100*1024)

        reader := bufio.NewReader(file)

        io.Copy(w, ratelimit.Reader(reader, bucket))

    } else {

        io.WriteString(w, "Invalid request.")

    }

}

但我收到此错误:


损坏的内容错误


由于检测到数据传输错误,无法显示您尝试查看的页面。


这是我在 Go 游乐场上的代码:http : //play.golang.org/p/ulgXQl4eQO


收到一只叮咚
浏览 556回答 2
2回答

慕码人8056858

我没有看到错误,但我确实注意到代码存在一些问题。为了这:w.Header().Set("Content-Type", r.Header.Get("Content-Type"))您应该使用mime 包的:func TypeByExtension(ext string) string确定内容类型。(如果你最终得到空字符串默认为application/octet-stream)为了:w.Header().Set("Content-Length", r.Header.Get("Content-Length"))您需要从文件本身获取内容长度。通过使用请求内容长度,对于 aGET这基本上以空操作结束,但是对于 aPOST您发送回错误的长度,这可能解释了您看到的错误。打开文件后,执行以下操作:fi, err := file.Stat()if err != nil {    http.Error(w, err.Error(), 500)    return}w.Header().Set("Content-Length", fmt.Sprint(fi.Size()))最后一件事,当您打开文件时,如果出现错误,您不需要关闭文件句柄。改为这样做:file, err := os.Open(...)if err != nil {    http.NotFound(w, r)    return}defer file.Close()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go