diff --git a/integration/copy_test.go b/integration/copy_test.go index 8bbf11c8..1c250ce9 100644 --- a/integration/copy_test.go +++ b/integration/copy_test.go @@ -463,3 +463,12 @@ func (s *SkopeoSuite) TestCopySrcAndDestWithAuth(c *check.C) { assertSkopeoSucceeds(c, "", "--tls-verify=false", "copy", "--dest-creds=testuser:testpassword", "docker://busybox", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url)) assertSkopeoSucceeds(c, "", "--tls-verify=false", "copy", "--src-creds=testuser:testpassword", "--dest-creds=testuser:testpassword", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url), fmt.Sprintf("docker://%s/test:auth", s.regV2WithAuth.url)) } + +func (s *CopySuite) TestCopyNoPanicOnHTTPResponseWOTLSVerifyFalse(c *check.C) { + const ourRegistry = "docker://" + v2DockerRegistryURL + "/" + + // dir:test isn't created beforehand just because we already know this could + // just fail when evaluating the src + assertSkopeoFails(c, ".*server gave HTTP response to HTTPS client.*", + "copy", ourRegistry+"foobar", "dir:test") +} diff --git a/vendor/github.com/containers/image/copy/copy.go b/vendor/github.com/containers/image/copy/copy.go index 857e650e..45fe8afd 100644 --- a/vendor/github.com/containers/image/copy/copy.go +++ b/vendor/github.com/containers/image/copy/copy.go @@ -153,7 +153,7 @@ func Image(policyContext *signature.PolicyContext, destRef, srcRef types.ImageRe } src, err := image.FromUnparsedImage(unparsedImage) if err != nil { - retErr = errors.Wrapf(err, "Error initializing image from source %s", transports.ImageName(srcRef)) + return errors.Wrapf(err, "Error initializing image from source %s", transports.ImageName(srcRef)) } unparsedImage = nil defer func() { diff --git a/vendor/github.com/containers/image/docker/docker_image_dest.go b/vendor/github.com/containers/image/docker/docker_image_dest.go index f19e8cfd..0d1b0234 100644 --- a/vendor/github.com/containers/image/docker/docker_image_dest.go +++ b/vendor/github.com/containers/image/docker/docker_image_dest.go @@ -100,27 +100,14 @@ func (c *sizeCounter) Write(p []byte) (n int, err error) { // If stream.Read() at any time, ESPECIALLY at end of input, returns an error, PutBlob MUST 1) fail, and 2) delete any data stored so far. func (d *dockerImageDestination) PutBlob(stream io.Reader, inputInfo types.BlobInfo) (types.BlobInfo, error) { if inputInfo.Digest.String() != "" { - checkURL := fmt.Sprintf(blobsURL, reference.Path(d.ref.ref), inputInfo.Digest.String()) - - logrus.Debugf("Checking %s", checkURL) - res, err := d.c.makeRequest("HEAD", checkURL, nil, nil) - if err != nil { + haveBlob, size, err := d.HasBlob(inputInfo) + if err != nil && err != types.ErrBlobNotFound { return types.BlobInfo{}, err } - defer res.Body.Close() - switch res.StatusCode { - case http.StatusOK: - logrus.Debugf("... already exists, not uploading") - return types.BlobInfo{Digest: inputInfo.Digest, Size: getBlobSize(res)}, nil - case http.StatusUnauthorized: - logrus.Debugf("... not authorized") - return types.BlobInfo{}, errors.Errorf("not authorized to read from destination repository %s", reference.Path(d.ref.ref)) - case http.StatusNotFound: - // noop - default: - return types.BlobInfo{}, errors.Errorf("failed to read from destination repository %s: %v", reference.Path(d.ref.ref), http.StatusText(res.StatusCode)) + // Now err == nil || err == types.ErrBlobNotFound + if err == nil && haveBlob { + return types.BlobInfo{Digest: inputInfo.Digest, Size: size}, nil } - logrus.Debugf("... failed, status %d", res.StatusCode) } // FIXME? Chunked upload, progress reporting, etc. @@ -199,10 +186,8 @@ func (d *dockerImageDestination) HasBlob(info types.BlobInfo) (bool, int64, erro logrus.Debugf("... not present") return false, -1, types.ErrBlobNotFound default: - logrus.Errorf("failed to read from destination repository %s: %v", reference.Path(d.ref.ref), http.StatusText(res.StatusCode)) + return false, -1, errors.Errorf("failed to read from destination repository %s: %v", reference.Path(d.ref.ref), http.StatusText(res.StatusCode)) } - logrus.Debugf("... failed, status %d, ignoring", res.StatusCode) - return false, -1, types.ErrBlobNotFound } func (d *dockerImageDestination) ReapplyBlob(info types.BlobInfo) (types.BlobInfo, error) { diff --git a/vendor/github.com/containers/image/manifest/manifest.go b/vendor/github.com/containers/image/manifest/manifest.go index 396f8111..430331f0 100644 --- a/vendor/github.com/containers/image/manifest/manifest.go +++ b/vendor/github.com/containers/image/manifest/manifest.go @@ -54,7 +54,7 @@ func GuessMIMEType(manifest []byte) string { } switch meta.MediaType { - case DockerV2Schema2MediaType, DockerV2ListMediaType: // A recognized type. + case DockerV2Schema2MediaType, DockerV2ListMediaType, imgspecv1.MediaTypeImageManifest, imgspecv1.MediaTypeImageManifestList: // A recognized type. return meta.MediaType } // this is the only way the function can return DockerV2Schema1MediaType, and recognizing that is essential for stripping the JWS signatures = computing the correct manifest digest.