From 51877cecf74c3844befa20762c1b97d6f38f34b8 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Thu, 15 Jun 2017 16:39:42 +0200 Subject: [PATCH] s3: Prevent closing of the reader for GCS --- src/restic/backend/s3/s3.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/restic/backend/s3/s3.go b/src/restic/backend/s3/s3.go index 7f14e72cd..beb557bdf 100644 --- a/src/restic/backend/s3/s3.go +++ b/src/restic/backend/s3/s3.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "io" + "io/ioutil" + "net/url" "os" "path" "restic" @@ -14,6 +16,7 @@ import ( "restic/errors" "github.com/minio/minio-go" + "github.com/minio/minio-go/pkg/s3utils" "restic/debug" ) @@ -22,6 +25,7 @@ import ( type Backend struct { client *minio.Client sem *backend.Semaphore + cfg Config bucketname string prefix string backend.Layout @@ -50,6 +54,7 @@ func Open(cfg Config) (restic.Backend, error) { be := &Backend{ client: client, sem: sem, + cfg: cfg, bucketname: cfg.Bucket, prefix: cfg.Prefix, } @@ -157,6 +162,19 @@ func (be *Backend) Path() string { return be.prefix } +func (be *Backend) isGoogleCloudStorage() bool { + scheme := "https://" + if be.cfg.UseHTTP { + scheme = "http://" + } + url, err := url.Parse(scheme + be.cfg.Endpoint) + if err != nil { + panic(err) + } + + return s3utils.IsGoogleEndpoint(*url) +} + // Save stores data in the backend at the handle. func (be *Backend) Save(ctx context.Context, h restic.Handle, rd io.Reader) (err error) { debug.Log("Save %v", h) @@ -174,6 +192,11 @@ func (be *Backend) Save(ctx context.Context, h restic.Handle, rd io.Reader) (err return errors.New("key already exists") } + // prevent GCS from closing the file + if be.isGoogleCloudStorage() { + rd = ioutil.NopCloser(rd) + } + be.sem.GetToken() debug.Log("PutObject(%v, %v)", be.bucketname, objName) n, err := be.client.PutObject(be.bucketname, objName, rd, "application/octet-stream")