...

Source file src/github.com/docker/distribution/registry/storage/io.go

Documentation: github.com/docker/distribution/registry/storage

     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  // limitReader returns a new reader limited to n bytes. Unlike io.LimitReader,
    32  // this returns an error when the limit reached.
    33  func limitReader(r io.Reader, n int64) io.Reader {
    34  	return &limitedReader{r: r, n: n}
    35  }
    36  
    37  // limitedReader implements a reader that errors when the limit is reached.
    38  //
    39  // Partially cribbed from net/http.MaxBytesReader.
    40  type limitedReader struct {
    41  	r   io.Reader // underlying reader
    42  	n   int64     // max bytes remaining
    43  	err error     // sticky 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  	// If they asked for a 32KB byte read but only 5 bytes are
    54  	// remaining, no need to read 32KB. 6 bytes will answer the
    55  	// question of the whether we hit the limit or go past it.
    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