Skip to content

Commit 6537515

Browse files
authored
ContainerRegistry: Tolerate a missing Location header in the manifest upload response (#27)
### Motivation According to distribution spec, the manifest `PUT` response [MUST contain a Location header](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-manifests) providing a URL from which the saved manifest can be downloaded. The same requirement applies to blob `PUT`s. However some registries return URLs which cannot be fetched, and ECR does not set this header at all. The location header is not currently of critical important. If the header is not present, we can create a suitable value based on the spec for [manifest downloads](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pulling-manifests). ### Modifications Generate a suitable manifest location URL when the registry does not provide one. ### Result Uploads to ECR will no longer fail because of the missing `Location` header in the manifest `PUT` response. ### Test Plan Automated tests continue to pass; manually tested with ECR.
1 parent bdb9cdb commit 6537515

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

Sources/ContainerRegistry/Manifests.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,14 @@ public extension RegistryClient {
2929
decodingErrors: [.notFound]
3030
)
3131

32-
guard let location = httpResponse.response.headerFields[.location] else {
33-
throw HTTPClientError.missingResponseHeader("Location")
34-
}
35-
return location
32+
// The distribution spec says the response MUST contain a Location header
33+
// providing a URL from which the saved manifest can be downloaded.
34+
// However some registries return URLs which cannot be fetched, and
35+
// ECR does not set this header at all.
36+
// If the header is not present, create a suitable value.
37+
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pulling-manifests
38+
return try httpResponse.response.headerFields[.location]
39+
?? registryURLForPath("/v2/\(repository)/manifests/\(manifest.digest)").absoluteString
3640
}
3741

3842
func getManifest(repository: String, reference: String) async throws -> ImageManifest {

0 commit comments

Comments
 (0)