Perform HEAD request, fall back to GET
parent
70c1b892ae
commit
5cd202fcef
|
@ -15,22 +15,24 @@ func (r *Registry) ManifestDigest(repository, reference string) (digest.Digest,
|
|||
url := r.url("/v2/%s/manifests/%s", repository, reference)
|
||||
r.Logf("registry.manifest.head url=%s repository=%s reference=%s", url, repository, reference)
|
||||
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
// Try HEAD request first because it's free
|
||||
resp, err := r.request("HEAD", url)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", strings.Join([]string{manifestv2.MediaTypeManifest, oci.MediaTypeImageIndex, oci.MediaTypeImageManifest}, ","))
|
||||
resp, err := r.Client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if hdr := resp.Header.Get("Docker-Content-Digest"); hdr != "" {
|
||||
return digest.Parse(hdr)
|
||||
}
|
||||
|
||||
// HEAD request didn't return a digest, attempt to fetch digest from body
|
||||
r.Logf("registry.manifest.get url=%s repository=%s reference=%s", url, repository, reference)
|
||||
resp, err = r.request("GET", url)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Try to get digest from body instead, should be equal to what would be presented
|
||||
// in Docker-Content-Digest
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
@ -39,3 +41,19 @@ func (r *Registry) ManifestDigest(repository, reference string) (digest.Digest,
|
|||
}
|
||||
return digest.FromBytes(body), nil
|
||||
}
|
||||
|
||||
// request performs a request against a url
|
||||
func (r *Registry) request(method string, url string) (*http.Response, error) {
|
||||
req, err := http.NewRequest(method, url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", strings.Join([]string{manifestv2.MediaTypeManifest, oci.MediaTypeImageIndex, oci.MediaTypeImageManifest}, ","))
|
||||
resp, err := r.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
@ -24,9 +26,13 @@ func TestGetDigest(t *testing.T) {
|
|||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
bodyBytes, _ := ioutil.ReadAll(resp.Body)
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("content-type", "application/vnd.docker.distribution.manifest.v2+json; charset=ISO-8859-1")
|
||||
io.Copy(w, resp.Body)
|
||||
|
||||
// Reset body for additional calls
|
||||
resp.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
|
|
Loading…
Reference in New Issue