// +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) } }