为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
收到一只叮咚 2021-09-27 17:22:11
我目前正在用 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
查看完整描述

2 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

我没有看到错误,但我确实注意到代码存在一些问题。为了这:


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


查看完整回答
反对 回复 2021-09-27
  • 2 回答
  • 0 关注
  • 555 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信