diff --git a/backend/s3/s3.go b/backend/s3/s3.go index 0c8795bc5..b5b7895fb 100644 --- a/backend/s3/s3.go +++ b/backend/s3/s3.go @@ -3,6 +3,7 @@ package s3 import ( "bytes" "errors" + "fmt" "io" "io/ioutil" "os" @@ -113,7 +114,7 @@ func (bb *s3Blob) Finalize(t backend.Type, name string) error { } <-bb.b.connChan - err = bb.b.s3api.PutObject(bb.b.bucketname, path, "application/octet-stream", int64(bb.buf.Len()), bb.buf) + err = bb.b.s3api.PutObject(bb.b.bucketname, path, "binary/octet-stream", int64(bb.buf.Len()), bb.buf) bb.b.connChan <- struct{}{} bb.buf.Reset() return err @@ -134,18 +135,34 @@ func (be *S3Backend) Create() (backend.Blob, error) { // name. The reader should be closed after draining it. func (be *S3Backend) Get(t backend.Type, name string) (io.ReadCloser, error) { path := s3path(t, name) - r, _, err := be.s3api.GetObject(be.bucketname, path) - rc := ioutil.NopCloser(r) + rc, _, err := be.s3api.GetObject(be.bucketname, path) return rc, err } // GetReader returns an io.ReadCloser for the Blob with the given name of // type t at offset and length. If length is 0, the reader reads until EOF. func (be *S3Backend) GetReader(t backend.Type, name string, offset, length uint) (io.ReadCloser, error) { - path := s3path(t, name) - r, _, err := be.s3api.GetPartialObject(be.bucketname, path, int64(offset), int64(length)) - rc := ioutil.NopCloser(r) - return rc, err + rc, err := be.Get(t, name) + if err != nil { + return nil, err + + } + + n, errc := io.CopyN(ioutil.Discard, rc, int64(offset)) + if errc != nil { + return nil, errc + + } else if n != int64(offset) { + return nil, fmt.Errorf("less bytes read than expected, read: %d, expected: %d", n, offset) + + } + + if length == 0 { + return rc, nil + + } + + return backend.LimitReadCloser(rc, int64(length)), nil } // Test returns true if a blob of the given type and name exists in the backend.