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

时间:2017-05-20 17:50:41

标签: go

这是使用golang将apk文件(几MB)上传到appetize.io的代码:

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\n", fileName, err)
        return nil, false
    }

    size, err := io.Copy(part, file)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error copying apk file data: %v\n", err)
        return nil, false
    }
    fmt.Fprintf(os.Stdout, "Copied %v bytes for uploading to appetize...\n", 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\n", 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
}

但是我在http.Post(...)行收到一个随机错误。它返回零响应和错误。错误是“流错误:流ID 1; REFUSED_STREAM”。它是随机发生的,但肯定会在go程序首次启动后发出请求时发生。

这是go版本:

go version go1.8.1 darwin/amd64

如果服务器没有失败,这是服务器的响应标头: enter image description here

我也在另一个运行1.6的Mac上运行这个程序。*,我不记得我在那个mac上遇到过这个问题。

知道发生了什么事吗?

1 个答案:

答案 0 :(得分:2)

golang标准库net/http中存在一个错误,无法正确处理REFUSED_STREAM http / 2错误。这是可能发生的事情:

  1. golang客户端打开与HTTP / 2 www服务器的TCP连接,将连接中的最大HTTP流数设置为1000并立即开始上传。

  2. HTTP / 2 www服务器告诉golang客户端只使用给定数量的流,但golang客户端已经启动了超过该数量的流。

  3. HTTP / 2 www服务器通过重置多余的流来对此作出反应。

  4. golang net/http代码中缺少对重试的适当支持会导致流在服务器重置后失败,并最终导致上传失败。

  5. 在github上有关于此问题的故障单:x/net/http2: retry requests rejected with REFUSED_STREAM - golang/go/issues/20985

    **此问题已在主分支中关闭,修复程序将包含在将来的Golang版本1.10中