ContainerRegistry: Remember initial auth challenge and send credentials eagerly #30
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Motivation
Currently,
ContainerRegistryhandles authentication lazily. First it tries an unauthenticated request. If the registry responds with a challenge,ContainerRegistrygets a suitable credential from.netrcor from an authentication service and re-tries the request.When pushing large blobs to some registries, the client can get stuck in a state where it has received an authentication challenge but is still waiting to finish the blob upload. The symptoms are that metadata uploads and very small image layers can be uploaded, but pushing larger images stalls and times out, as reported in #17.
Modifications
When pushing large blobs, the registry's
401challenge arrives after the client has sent some of the blob data, but before it has completed the upload. With some registries,URLSessiongets stuck in this state. Implementing thedidReceiveResponsedelegate allows the client to see the challenge and cancel the task but in some cases, mainly on Linux,URLSessioncan still get stuck.A more reliable solution to this problem is to handle challenges eagerly. Before pushing any data, the client checks whether the registry supports the v2 distribution protocol. If it is challenged during this check, it will then eagerly send a suitable authentication token with all subsequent requests to the registry. This avoids the state where the client receives a challenge part-way through uploading a large blob and gets stuck.
Result
It is possible to upload large images to ECR and Docker Hub from macOS hosts, and to Docker Hub from Linux hosts. Uploading to ECR from Linux hosts continues to lead to a timeout.
Fixes #17
Test Plan
Automated tests continue to pass; tested manually with several different registries.