From f731acaa33dc51444fa4cbc77db9d6571f6de826 Mon Sep 17 00:00:00 2001 From: Valentin Delaye Date: Sat, 7 Feb 2026 08:16:28 +0100 Subject: [PATCH] Avoid HEAD request before getting blobs Signed-off-by: Valentin Delaye --- src/main/java/land/oras/Registry.java | 10 +--------- src/test/java/land/oras/PublicECRITCase.java | 21 +++++++++++++++++++- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/main/java/land/oras/Registry.java b/src/main/java/land/oras/Registry.java index f362152..33be6a2 100644 --- a/src/main/java/land/oras/Registry.java +++ b/src/main/java/land/oras/Registry.java @@ -354,6 +354,7 @@ public Manifest pushArtifact( public Layer pushBlob(ContainerRef containerRef, Path blob, Map annotations) { String digest = containerRef.getAlgorithm().digest(blob); LOG.debug("Digest: {}", digest); + // This migh not works with registries performing HEAD request if (hasBlob(containerRef.withDigest(digest))) { LOG.info("Blob already exists: {}", digest); return Layer.fromFile(blob, containerRef.getAlgorithm()).withAnnotations(annotations); @@ -491,9 +492,6 @@ private HttpClient.ResponseWrapper headBlob(ContainerRef containerRef) { */ @Override public byte[] getBlob(ContainerRef containerRef) { - if (!hasBlob(containerRef)) { - throw new OrasException(new HttpClient.ResponseWrapper<>("", 404, Map.of())); - } URI uri = URI.create( "%s://%s".formatted(getScheme(), containerRef.forRegistry(this).getBlobsPath(this))); HttpClient.ResponseWrapper response = client.get( @@ -510,9 +508,6 @@ public byte[] getBlob(ContainerRef containerRef) { @Override public void fetchBlob(ContainerRef containerRef, Path path) { - if (!hasBlob(containerRef)) { - throw new OrasException(new HttpClient.ResponseWrapper<>("", 404, Map.of())); - } URI uri = URI.create( "%s://%s".formatted(getScheme(), containerRef.forRegistry(this).getBlobsPath(this))); HttpClient.ResponseWrapper response = client.download( @@ -528,9 +523,6 @@ public void fetchBlob(ContainerRef containerRef, Path path) { @Override public InputStream fetchBlob(ContainerRef containerRef) { - if (!hasBlob(containerRef)) { - throw new OrasException(new HttpClient.ResponseWrapper<>("", 404, Map.of())); - } URI uri = URI.create( "%s://%s".formatted(getScheme(), containerRef.forRegistry(this).getBlobsPath(this))); HttpClient.ResponseWrapper response = client.download( diff --git a/src/test/java/land/oras/PublicECRITCase.java b/src/test/java/land/oras/PublicECRITCase.java index 0de3a11..bb76a24 100644 --- a/src/test/java/land/oras/PublicECRITCase.java +++ b/src/test/java/land/oras/PublicECRITCase.java @@ -22,11 +22,12 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -@Execution(ExecutionMode.CONCURRENT) +@Execution(ExecutionMode.SAME_THREAD) // Avoid 429 Too Many Requests for unauthenticated requests to public ECR class PublicECRITCase { @Test @@ -44,4 +45,22 @@ void shouldPullAnonymousIndex() { Index index2 = registry.getIndex(containerRef2); assertNotNull(index2); } + + @Test + @Disabled("https://github.com/oras-project/oras-java/issues/522") + void shouldPullManifest() { + Registry registry = Registry.builder().build(); + ContainerRef containerRef = ContainerRef.parse( + "public.ecr.aws/docker/library/alpine@sha256:59855d3dceb3ae53991193bd03301e082b2a7faa56a514b03527ae0ec2ce3a95"); + Manifest manifest = registry.getManifest(containerRef); + assertNotNull(manifest); + } + + @Test + void shouldPullLayer() { + Registry registry = Registry.builder().build(); + ContainerRef containerRef = ContainerRef.parse( + "public.ecr.aws/docker/library/alpine@sha256:589002ba0eaed121a1dbf42f6648f29e5be55d5c8a6ee0f8eaa0285cc21ac153"); + registry.getBlob(containerRef); + } }