forked from TrueCloudLab/distribution
Explicitly select digest method for content
Detecting tar files then falling back for calculating digests turned out to be fairly unreliable. Likely, the implementation was broken for content that was not a tarfile. Also, for the use case of the registry, it is really not needed. This functionality has been removed in FromReader and FromBytes. FromTarArchive has been added for convenience. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
972a95f077
commit
10a4605ec2
2 changed files with 17 additions and 21 deletions
|
@ -36,6 +36,11 @@ func NewDigest(alg string, h hash.Hash) Digest {
|
|||
return Digest(fmt.Sprintf("%s:%x", alg, h.Sum(nil)))
|
||||
}
|
||||
|
||||
// NewDigestFromHex returns a Digest from alg and a the hex encoded digest.
|
||||
func NewDigestFromHex(alg, hex string) Digest {
|
||||
return Digest(fmt.Sprintf("%s:%s", alg, hex))
|
||||
}
|
||||
|
||||
// DigestRegexp matches valid digest types.
|
||||
var DigestRegexp = regexp.MustCompile(`[a-zA-Z0-9-_+.]+:[a-zA-Z0-9-_+.=]+`)
|
||||
|
||||
|
@ -57,33 +62,24 @@ func ParseDigest(s string) (Digest, error) {
|
|||
|
||||
// FromReader returns the most valid digest for the underlying content.
|
||||
func FromReader(rd io.Reader) (Digest, error) {
|
||||
|
||||
// TODO(stevvooe): This is pretty inefficient to always be calculating a
|
||||
// sha256 hash to provide fallback, but it provides some nice semantics in
|
||||
// that we never worry about getting the right digest for a given reader.
|
||||
// For the most part, we can detect tar vs non-tar with only a few bytes,
|
||||
// so a scheme that saves those bytes would probably be better here.
|
||||
|
||||
h := sha256.New()
|
||||
tr := io.TeeReader(rd, h)
|
||||
|
||||
ts, err := tarsum.NewTarSum(tr, true, tarsum.Version1)
|
||||
if _, err := io.Copy(h, rd); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return NewDigest("sha256", h), nil
|
||||
}
|
||||
|
||||
// FromTarArchive produces a tarsum digest from reader rd.
|
||||
func FromTarArchive(rd io.Reader) (Digest, error) {
|
||||
ts, err := tarsum.NewTarSum(rd, true, tarsum.Version1)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Try to copy from the tarsum, if we fail, copy the remaining bytes into
|
||||
// hash directly.
|
||||
if _, err := io.Copy(ioutil.Discard, ts); err != nil {
|
||||
if err.Error() != "archive/tar: invalid tar header" {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if _, err := io.Copy(h, rd); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return NewDigest("sha256", h), nil
|
||||
return "", err
|
||||
}
|
||||
|
||||
d, err := ParseDigest(ts.Sum(nil))
|
||||
|
|
|
@ -30,7 +30,7 @@ func TestDigestVerifier(t *testing.T) {
|
|||
t.Fatalf("error creating tarfile: %v", err)
|
||||
}
|
||||
|
||||
digest, err = FromReader(tf)
|
||||
digest, err = FromTarArchive(tf)
|
||||
if err != nil {
|
||||
t.Fatalf("error digesting tarsum: %v", err)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue