mirror of https://github.com/restic/restic.git
rest: workaround for HTTP2 zero-length replies bug
The golang http client does not return an error when a HTTP2 reply includes a non-zero content length but does not return any data at all. This scenario can occur e.g. when using rclone when a file stored in a backend seems to be accessible but then fails to download.
This commit is contained in:
parent
790294dc26
commit
185a55026b
|
@ -9,6 +9,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/net/context/ctxhttp"
|
"golang.org/x/net/context/ctxhttp"
|
||||||
|
@ -246,6 +247,20 @@ func (b *Backend) openReader(ctx context.Context, h restic.Handle, length int, o
|
||||||
return nil, errors.Errorf("unexpected HTTP response (%v): %v", resp.StatusCode, resp.Status)
|
return nil, errors.Errorf("unexpected HTTP response (%v): %v", resp.StatusCode, resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// workaround https://github.com/golang/go/issues/46071
|
||||||
|
// see also https://forum.restic.net/t/http2-stream-closed-connection-reset-context-canceled/3743/10
|
||||||
|
if resp.ContentLength == 0 && resp.ProtoMajor == 2 && resp.ProtoMinor == 0 {
|
||||||
|
if clens := resp.Header["Content-Length"]; len(clens) == 1 {
|
||||||
|
if cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil {
|
||||||
|
resp.ContentLength = int64(cl)
|
||||||
|
}
|
||||||
|
if resp.ContentLength != 0 {
|
||||||
|
_ = resp.Body.Close()
|
||||||
|
return nil, errors.Errorf("unexpected EOF got 0 instead of %v bytes", resp.ContentLength)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return resp.Body, nil
|
return resp.Body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue