duancui19840401 2017-05-20 17:50
浏览 154
已采纳

随机REFUSED_STREAM发出POST多部分表格请求

This is the code to upload an apk file (several MB) to appetize.io using golang:

func uploadToAppetize(file multipart.File, branchName string, displayName string) (result *AppetizeRes, ok bool) {
    file.Seek(0, 0)
    url, _ := getUrl()
    var buffer bytes.Buffer
    writer := multipart.NewWriter(&buffer)
    fileName := displayName + "/" + branchName
    part, err := writer.CreateFormFile("file", fileName)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error creating form file %v: %v
", fileName, err)
        return nil, false
    }

    size, err := io.Copy(part, file)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error copying apk file data: %v
", err)
        return nil, false
    }
    fmt.Fprintf(os.Stdout, "Copied %v bytes for uploading to appetize...
", size)
    writer.Close()
    response, err := http.Post(url, writer.FormDataContentType(), &buffer) // Random error on this line
    if err != nil || response == nil {
        fmt.Fprintf(os.Stderr, "Error occurred uploading apk data to appetize.io: %v %v
", err, response)
        return nil, false
    }
    defer response.Body.Close()
    if response.StatusCode != http.StatusOK {
        return nil, false
    }

    var appetizeRes AppetizeRes
    if err := json.NewDecoder(response.Body).Decode(&appetizeRes); err != nil {
        return nil, false
    }
    return &appetizeRes, true
}

However I am receiving an random error on the line http.Post(...). It returns a nil response and an error. The error is "stream error: stream ID 1; REFUSED_STREAM". It happens randomly but will surely happen the first time the go program make the request after launching.

This is the go version:

go version go1.8.1 darwin/amd64

This is the response header from the server if it doesn't fail: enter image description here

I also run this program on another mac running go 1.6.*, I didn't remember I ever run into this issue on that mac.

Any idea what's going on?

  • 写回答

1条回答 默认 最新

  • douzhi1924 2017-08-01 17:15
    关注

    There is a bug in the golang standard library net/http that fails to handle the REFUSED_STREAM http/2 error properly. This is what is likely going on:

    1. golang client opens a TCP connection to the HTTP/2 www server, sets the maximum number of HTTP streams in the connection to 1000 and starts uploading immediately.

    2. The HTTP/2 www server tells the golang client to only use a given number of streams, but the golang client has already started more than that amount of streams.

    3. The HTTP/2 www server reacts to this by resetting the excess streams.

    4. The lack of proper support for a retry in the golang net/http code causes the stream to fail after being reset by the server, and eventually the upload fails as well.

    There is a ticket open about this issue on github: x/net/http2: retry requests rejected with REFUSED_STREAM - golang/go/issues/20985

    **This issue has been closed in the master branch, the fix will be included in future Golang version 1.10

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 易语言把MYSQL数据库中的数据添加至组合框
  • ¥20 求数据集和代码#有偿答复
  • ¥15 关于下拉菜单选项关联的问题
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况