Skip to content

Commit

Permalink
Add knownDigest to ociclient's Resolve* methods
Browse files Browse the repository at this point in the history
In the OCI spec, having `HEAD` requests return the digest header is technically only a "SHOULD" (not a "MUST"), and it turns out that Docker Hub is one of the registries on the sad side of that "SHOULD" -- the code elsewhere was already accounting for this via the `knownDigest` parameter to `descriptorFromResponse`, but it was (accidentally?) set to `""` explicitly for all the `resolve` methods (even though 2 out of 3 of them are by-digest):

https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#checking-if-content-exists-in-the-registry

> A HEAD request to an existing blob or manifest URL MUST return `200 OK`. A successful response SHOULD contain the digest of the uploaded blob in the header `Docker-Content-Digest`. A successful response SHOULD contain the size in bytes of the uploaded blob in the header `Content-Length`.

As a result, my attempts at using `ResolveBlob` to check if a specific blob exists on Docker Hub were failing with "invalid descriptor in response: no digest found in response" even though the proper digest was in the request and the response was 200 OK:

```console
$ curl -H "$(crane auth token --header busybox)" --head -L https://registry-1.docker.io/v2/library/busybox/blobs/sha256:7b2699543f22d5b8dc8d66a5873eb246767bca37232dee1e7a3b8c9956bceb0c
HTTP/1.1 307 Temporary Redirect
content-type: application/octet-stream
docker-distribution-api-version: registry/2.0
location: https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/7b/7b2699543f22d5b8dc8d66a5873eb246767bca37232dee1e7a3b8c9956bceb0c/data?verify=1709871346-z5HS81nN1Ov9OEB3RdN60eJ2MjA%3D
date: Fri, 08 Mar 2024 03:25:46 GMT
strict-transport-security: max-age=31536000

HTTP/2 200
date: Fri, 08 Mar 2024 03:25:46 GMT
content-type: application/octet-stream
content-length: 2152262
cf-ray: 860fb84bfd2f2b58-LAX
cf-cache-status: HIT
accept-ranges: bytes
age: 170784
cache-control: public, max-age=14400
etag: "2aeecf61106ed1c6e3a774e3db220ca7"
expires: Fri, 08 Mar 2024 07:25:46 GMT
last-modified: Wed, 06 Mar 2024 00:07:43 GMT
vary: Accept-Encoding
x-amz-id-2: GIEh93BaQl88NHOZYTVLgwDtBjOzY96VsTcyP2qql4lrK98VY+vcj1wOxHAT47ChDa+wRCKv7Pk=
x-amz-request-id: 8YB4XDY06KMSY2GN
x-amz-server-side-encryption: AES256
x-amz-version-id: oxJ9x0zrl0ICqBGgSAIDsycrCQ9qVxw5
server: cloudflare
```

I have verified that this fixes the issue and allows the `ResolveBlob` call to complete successfully against Docker Hub.

Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
  • Loading branch information
tianon committed Mar 12, 2024
1 parent 2bd90cc commit 1096806
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 3 deletions.
4 changes: 2 additions & 2 deletions ociregistry/ociclient/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (c *client) resolve(ctx context.Context, rreq *ocirequest.Request) (ociregi
return ociregistry.Descriptor{}, err
}
resp.Body.Close()
desc, err := descriptorFromResponse(resp, "", true)
desc, err := descriptorFromResponse(resp, ociregistry.Digest(rreq.Digest), true)
if err != nil {
return ociregistry.Descriptor{}, fmt.Errorf("invalid descriptor in response: %v", err)
}
Expand Down Expand Up @@ -173,7 +173,7 @@ func (c *client) read(ctx context.Context, rreq *ocirequest.Request) (_ ociregis
return nil, err
}
resp1.Body.Close()
desc, err = descriptorFromResponse(resp1, "", true)
desc, err = descriptorFromResponse(resp1, ociregistry.Digest(rreq1.Digest), true)
if err != nil {
return nil, err
}
Expand Down
4 changes: 3 additions & 1 deletion ociregistry/ociserver/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ func (r *registry) handleManifestHead(ctx context.Context, resp http.ResponseWri
if err != nil {
return err
}
resp.Header().Set("Docker-Content-Digest", string(desc.Digest))
if !r.opts.OmitDigestFromTagGetResponse {
resp.Header().Set("Docker-Content-Digest", string(desc.Digest))
}
resp.Header().Set("Content-Type", desc.MediaType)
resp.Header().Set("Content-Length", fmt.Sprint(desc.Size))
resp.WriteHeader(http.StatusOK)
Expand Down

0 comments on commit 1096806

Please sign in to comment.