Merge pull request #2221 from AkihiroSuda/content-small-blob
services/content: fix reading a blob which is smaller than the read buffer
This commit is contained in:
commit
ad6d02b881
@ -46,6 +46,7 @@ func ContentSuite(t *testing.T, name string, storeFn func(ctx context.Context, r
|
||||
t.Run("ResumeCopy", makeTest(t, name, storeFn, checkResume(resumeCopy)))
|
||||
t.Run("ResumeCopySeeker", makeTest(t, name, storeFn, checkResume(resumeCopySeeker)))
|
||||
t.Run("ResumeCopyReaderAt", makeTest(t, name, storeFn, checkResume(resumeCopyReaderAt)))
|
||||
t.Run("SmallBlob", makeTest(t, name, storeFn, checkSmallBlob))
|
||||
t.Run("Labels", makeTest(t, name, storeFn, checkLabels))
|
||||
|
||||
t.Run("CrossNamespaceAppend", makeTest(t, name, storeFn, checkCrossNSAppend))
|
||||
@ -523,6 +524,46 @@ func resumeCopyReaderAt(ctx context.Context, w content.Writer, b []byte, _, size
|
||||
return errors.Wrap(content.Copy(ctx, w, r, size, dgst), "copy failed")
|
||||
}
|
||||
|
||||
// checkSmallBlob tests reading a blob which is smaller than the read size.
|
||||
func checkSmallBlob(ctx context.Context, t *testing.T, store content.Store) {
|
||||
blob := []byte(`foobar`)
|
||||
blobSize := int64(len(blob))
|
||||
blobDigest := digest.FromBytes(blob)
|
||||
// test write
|
||||
w, err := store.Writer(ctx, t.Name(), blobSize, blobDigest)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := w.Write(blob); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := w.Commit(ctx, blobSize, blobDigest); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// test read.
|
||||
readSize := blobSize + 1
|
||||
ra, err := store.ReaderAt(ctx, blobDigest)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := io.NewSectionReader(ra, 0, readSize)
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ra.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
d := digest.FromBytes(b)
|
||||
if blobDigest != d {
|
||||
t.Fatalf("expected %s (%q), got %s (%q)", blobDigest, string(blob),
|
||||
d, string(b))
|
||||
}
|
||||
}
|
||||
|
||||
func checkCrossNSShare(ctx context.Context, t *testing.T, cs content.Store) {
|
||||
wrap, ok := ctx.Value(wrapperKey{}).(ContextWrapper)
|
||||
if !ok {
|
||||
|
@ -187,6 +187,8 @@ func (s *service) Read(req *api.ReadContentRequest, session api.Content_ReadServ
|
||||
|
||||
var (
|
||||
offset = req.Offset
|
||||
// size is read size, not the expected size of the blob (oi.Size), which the caller might not be aware of.
|
||||
// offset+size can be larger than oi.Size.
|
||||
size = req.Size_
|
||||
|
||||
// TODO(stevvooe): Using the global buffer pool. At 32KB, it is probably
|
||||
@ -199,12 +201,12 @@ func (s *service) Read(req *api.ReadContentRequest, session api.Content_ReadServ
|
||||
offset = 0
|
||||
}
|
||||
|
||||
if size <= 0 {
|
||||
size = oi.Size - offset
|
||||
if offset > oi.Size {
|
||||
return status.Errorf(codes.OutOfRange, "read past object length %v bytes", oi.Size)
|
||||
}
|
||||
|
||||
if offset+size > oi.Size {
|
||||
return status.Errorf(codes.OutOfRange, "read past object length %v bytes", oi.Size)
|
||||
if size <= 0 || offset+size > oi.Size {
|
||||
size = oi.Size - offset
|
||||
}
|
||||
|
||||
_, err = io.CopyBuffer(
|
||||
|
Loading…
Reference in New Issue
Block a user