...
1 package storage
2
3 import (
4 "context"
5 "errors"
6 "io"
7 "io/ioutil"
8
9 "github.com/docker/distribution/registry/storage/driver"
10 )
11
12 const (
13 maxBlobGetSize = 4 << 20
14 )
15
16 func getContent(ctx context.Context, driver driver.StorageDriver, p string) ([]byte, error) {
17 r, err := driver.Reader(ctx, p, 0)
18 if err != nil {
19 return nil, err
20 }
21 defer r.Close()
22
23 return readAllLimited(r, maxBlobGetSize)
24 }
25
26 func readAllLimited(r io.Reader, limit int64) ([]byte, error) {
27 r = limitReader(r, limit)
28 return ioutil.ReadAll(r)
29 }
30
31
32
33 func limitReader(r io.Reader, n int64) io.Reader {
34 return &limitedReader{r: r, n: n}
35 }
36
37
38
39
40 type limitedReader struct {
41 r io.Reader
42 n int64
43 err error
44 }
45
46 func (l *limitedReader) Read(p []byte) (n int, err error) {
47 if l.err != nil {
48 return 0, l.err
49 }
50 if len(p) == 0 {
51 return 0, nil
52 }
53
54
55
56 if int64(len(p)) > l.n+1 {
57 p = p[:l.n+1]
58 }
59 n, err = l.r.Read(p)
60
61 if int64(n) <= l.n {
62 l.n -= int64(n)
63 l.err = err
64 return n, err
65 }
66
67 n = int(l.n)
68 l.n = 0
69
70 l.err = errors.New("storage: read exceeds limit")
71 return n, l.err
72 }
73
View as plain text