diff --git a/internal/backend/rest/rest_int_go114_test.go b/internal/backend/rest/rest_int_go114_test.go new file mode 100644 index 000000000..036a136e1 --- /dev/null +++ b/internal/backend/rest/rest_int_go114_test.go @@ -0,0 +1,94 @@ +// +build go1.14 + +package rest_test + +import ( + "context" + "io" + "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + "github.com/restic/restic/internal/backend/rest" + "github.com/restic/restic/internal/restic" +) + +func TestZeroLengthRead(t *testing.T) { + // Test workaround for https://github.com/golang/go/issues/46071. Can be removed once this is fixed in Go + // and the minimum golang version supported by restic includes the fix. + numRequests := 0 + srv := httptest.NewUnstartedServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + numRequests++ + t.Logf("req %v %v", req.Method, req.URL.Path) + if req.Method == "GET" { + res.Header().Set("Content-Length", "42") + // Now the handler fails for some reason and is unable to send data + return + } + + t.Errorf("unhandled request %v %v", req.Method, req.URL.Path) + })) + srv.EnableHTTP2 = true + srv.StartTLS() + defer srv.Close() + + srvURL, err := url.Parse(srv.URL) + if err != nil { + t.Fatal(err) + } + + cfg := rest.Config{ + Connections: 5, + URL: srvURL, + } + be, err := rest.Open(cfg, srv.Client().Transport) + if err != nil { + t.Fatal(err) + } + defer func() { + err = be.Close() + if err != nil { + t.Fatal(err) + } + }() + + err = be.Load(context.TODO(), restic.Handle{Type: restic.ConfigFile}, 0, 0, func(rd io.Reader) error { + _, err := ioutil.ReadAll(rd) + if err == nil { + t.Fatal("ReadAll should have returned an 'Unexpected EOF' error") + } + return nil + }) + if err == nil { + t.Fatal("Got no unexpected EOF error") + } +} + +func TestGolangZeroLengthRead(t *testing.T) { + // This test is intended to fail once the underlying issue has been fixed in Go + ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Length", "42") + // Now the handler fails for some reason and is unable to send data + })) + ts.EnableHTTP2 = true + ts.StartTLS() + defer ts.Close() + + res, err := ts.Client().Get(ts.URL) + if err != nil { + t.Fatal(err) + } + _, err = ioutil.ReadAll(res.Body) + defer func() { + err = res.Body.Close() + if err != nil { + t.Fatal(err) + } + }() + if err != nil { + // This should fail with an 'Unexpected EOF' error + t.Fatal(err) + } +}