-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SUPERCEDED] Standardize and disambiguate the return from digest.Parse
#76
Conversation
1ec2594
to
6c1940b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some comments, but I'm a bit confused about the change itself; IIUC from the linked issue, the issue you're trying to resolve is a registry that doesn't return the Docker-Content-Digest
header. The code in this repository only provides the tools to perform the validation, but does not handle reading the Docker-Content-Digest
specifically (i.e., greping for that string does not produce a result in the source code).
Note that the header is optional but if it's returned by the registry, it should contain a valid digest. From the spec;
Legacy Docker support HTTP headers
Because of the origins this specification, the client MAY encounter Docker-specific headers, such as
Docker-Content-Digest
, orDocker-Distribution-API-Version
. These headers are OPTIONAL and clients SHOULD NOT depend on them.
However, IF the header is present, and IF the client uses the header, it MUST be validated;
A GET request to an existing manifest URL MUST provide the expected manifest, with a response code that MUST be
200 OK
.
A successful response SHOULD contain the digest of the uploaded blob in the headerDocker-Content-Digest
.The
Docker-Content-Digest
header, if present on the response, returns the canonical digest of the uploaded blob which MAY differ from the provided digest.
If the digest does differ, it MAY be the case that the hashing algorithms used do not match.
See Content Digests apdx-3 for information on how to detect the hashing algorithm in use.
Most clients MAY ignore the value, but if it is used, the client MUST verify the value against the uploaded blob data.
So if the registry is not returning a Docker-Content-Digest
, no validation is performed with it, but if it does return the header, it should be valid; which means that if the registry returns an empty value, there's a bug in that registry implementation, and it doesn't comply with the specification.
if err := d.Validate(); err != nil { | ||
return "", err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 the existing code looks a bit odd indeed (always returning the digest, even if it didn't validate).
However, it looks like there's some code that uses the returned value even if there's an error;
Lines 95 to 103 in bde1400
dgst, err := digest.Parse(d) | |
if err == digest.ErrDigestInvalidFormat { | |
hex = d | |
searchFunc = func(i int) bool { | |
return dst.entries[i].val >= d | |
} | |
} else { | |
hex = dgst.Hex() | |
alg = dgst.Algorithm() |
(i.e., it only considers the error if it's a digest.ErrDigestInvalidFormat
). Not sure if that's a bug, or if that's intentional (in either case, the documentation of this function should be updated to explain, and the code I linked to could use some comments as well)
@dmcgowan I see you wrote that code in 77570c9 (#55) perhaps you recall?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made a change that I think should address this (valid) issue that you've picked up with the change I made. Let me know if you think it seems reasonable to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not keep the previous code?
69926df
to
7f14c37
Compare
Thank you again for the detailed review here @thaJeztah. I agree with everything you've pointed out here, and I've reverted the change in The changes that remain now are:
What are your thoughts on these?
|
5bc3115
to
774d105
Compare
774d105
to
6b741e5
Compare
765f894
to
6b741e5
Compare
Hi @thaJeztah, when you get some time could you please take a look at this change and give me your feedback and list of concerns? |
Specifically, either return (<something>, nil), or (<nothing>, err), but not (<something>, err) which is difficult to reason about. Add two abstraction helper methods: `IsIdenticalTo`, and `IsEmpty` Signed-off-by: Nima Talebi <[email protected]>
6b741e5
to
18ee753
Compare
The PR title and the description text is confusing. |
// IsIdenticalTo compares this digest to any other, inclusive of the hashing algorithm used | ||
func (d Digest) IsIdenticalTo(o Digest) bool { | ||
return string(d) == string(o) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be probably a separate PR
func (d Digest) Hex() string { | ||
return d.Encoded() | ||
} | ||
|
||
// IsEmpty does what it says (an empty digest is an empty string) | ||
func (d Digest) IsEmpty() bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one too
I've dropped the dependency on this change in And @AkihiroSuda I'm happy to move them, just want to make sure that I'm not the only one that thinks it's a good idea to have these new helper/abstraction methods. Thank you for the review too. |
I'll clean this up now and split it into two separate PRs. |
digest.Parse
digest.Parse
digest.Parse
[SUPERCEDED]
digest.Parse
[SUPERCEDED]digest.Parse
Please see oras-project/oras-go#225 and oras-project/oras-go#237 for background.Superseded by #77, #78