这是使用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
我也在另一个运行1.6的Mac上运行这个程序。*,我不记得我在那个mac上遇到过这个问题。
知道发生了什么事吗?
答案 0 :(得分:2)
golang标准库net/http
中存在一个错误,无法正确处理REFUSED_STREAM
http / 2错误。这是可能发生的事情:
golang客户端打开与HTTP / 2 www服务器的TCP连接,将连接中的最大HTTP流数设置为1000并立即开始上传。
HTTP / 2 www服务器告诉golang客户端只使用给定数量的流,但golang客户端已经启动了超过该数量的流。
HTTP / 2 www服务器通过重置多余的流来对此作出反应。
golang net/http
代码中缺少对重试的适当支持会导致流在服务器重置后失败,并最终导致上传失败。
在github上有关于此问题的故障单:x/net/http2: retry requests rejected with REFUSED_STREAM - golang/go/issues/20985
**此问题已在主分支中关闭,修复程序将包含在将来的Golang版本1.10中