Calculate digest when missing from registry response headers (#188)

Closes #186
This commit is contained in:
Matteo Castellini 2019-10-06 11:25:02 +02:00 committed by Manuel Vogel
parent 9811d4d5f0
commit f3e27203d1
2 changed files with 45 additions and 2 deletions

View file

@ -1,6 +1,7 @@
package docker
import (
"crypto/sha256"
"crypto/tls"
"encoding/json"
"fmt"
@ -119,7 +120,7 @@ func getImageDigest(registry, image, tag, username, password string, fallback bo
switch resp.StatusCode {
// Basic auth was valid or not needed
case http.StatusOK:
return resp.Header.Get("Docker-Content-Digest"), nil
return getDigestFromResponse(resp)
// Either OAuth is required or the basic auth creds were invalid
case http.StatusUnauthorized:
@ -170,7 +171,7 @@ func getImageDigest(registry, image, tag, username, password string, fallback bo
return "", fmt.Errorf("Got bad response from registry: " + digestResponse.Status)
}
return digestResponse.Header.Get("Docker-Content-Digest"), nil
return getDigestFromResponse(digestResponse)
}
return "", fmt.Errorf("Bad credentials: " + resp.Status)
@ -200,3 +201,18 @@ func parseAuthHeader(header string) map[string]string {
return opts
}
func getDigestFromResponse(response *http.Response) (string, error) {
header := response.Header.Get("Docker-Content-Digest")
if header == "" {
body, err := ioutil.ReadAll(response.Body)
if err != nil {
return "", fmt.Errorf("Error reading registry response body: %s", err)
}
return fmt.Sprintf("sha256:%x", sha256.Sum256(body)), nil
}
return header, nil
}

View file

@ -1,7 +1,10 @@
package docker
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"regexp"
"testing"
@ -82,3 +85,27 @@ data "docker_registry_image" "foobar" {
name = "%s"
}
`
func TestGetDigestFromResponse(t *testing.T) {
headerContent := "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"
respWithHeaders := &http.Response{
Header: http.Header{
"Docker-Content-Digest": []string{headerContent},
},
Body: ioutil.NopCloser(bytes.NewReader([]byte("foo"))),
}
if digest, _ := getDigestFromResponse(respWithHeaders); digest != headerContent {
t.Errorf("Expected digest from header to be %s, but was %s", headerContent, digest)
}
bodyDigest := "sha256:fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9"
respWithoutHeaders := &http.Response{
Header: make(http.Header),
Body: ioutil.NopCloser(bytes.NewReader([]byte("bar"))),
}
if digest, _ := getDigestFromResponse(respWithoutHeaders); digest != bodyDigest {
t.Errorf("Expected digest calculated from body to be %s, but was %s", bodyDigest, digest)
}
}