Send a User-Agent header on registry requests - #753
Conversation
|
@adityasingh2400 Can you set push this with signed commits? We require that for merging. Also, please rebase to the latest main to pick up a GH workflow change that fixes a test failure unrelated to your work. Thank you! See also: https://github.com/apple/containerization/blob/main/CONTRIBUTING.md#pull-requests |
|
@adityasingh2400 Your commit is signed but unverified. The email that you use for your signing key needs to match an email that you've registered in your Github profile. |
|
@adityasingh2400 Also, please run |
Registry requests built by RegistryClient went out without a User-Agent
header. The central request() method constructed an HTTPClientRequest and
only ever set Authorization plus any caller-supplied headers, and
AsyncHTTPClient does not add a default User-Agent of its own, so every
registry operation (manifest resolves, blob fetches, token exchanges, and
pushes) was anonymous on the wire.
HTTP/1.1 only recommends User-Agent rather than requiring it, but in
practice some registries and forward proxies reject, rate-limit, or
otherwise mishandle requests that omit it, and operators rely on it for
attribution and debugging.
The client already carried a clientID ("containerization-registry-client"
by default), but it was only used as the OAuth client_id form field when
fetching tokens, never as an HTTP header. Set the User-Agent from clientID
at the single point where requests are constructed so it applies uniformly
to every registry call including retries and token fetches. A caller that
passes its own User-Agent in the per-request headers still takes
precedence, and no duplicate header is emitted.
34296b5 to
b13b30e
Compare
|
Thanks for the pointers, all three are done. The signature problem was a repo-local I also rebased onto the latest main to pick up the workflow fix, and re-ran Ready for another CI run whenever you are. |
Registry requests built by
RegistryClientgo out without aUser-Agentheader. The centralrequest()method constructs anHTTPClientRequestand only ever setsAuthorizationplus whatever caller headers are passed, andAsyncHTTPClientdoes not add a defaultUser-Agentof its own. As a result every registry operation (manifest resolves, blob fetches, token exchanges, and pushes) is anonymous on the wire, which is what the issue reporter saw when proxying the traffic.HTTP/1.1 only recommends
User-Agentrather than requiring it, but in practice some registries and forward proxies reject, rate-limit, or otherwise mishandle requests that omit it, and operators rely on it for attribution and debugging.The client already carries a
clientID(containerization-registry-clientby default), but it was only used as the OAuthclient_idform field when fetching tokens, never as an HTTP header. This sets theUser-AgentfromclientIDat the single point where requests are constructed, so it applies uniformly to every registry call including retries and token fetches. A caller that supplies its ownUser-Agentin the per-request headers still takes precedence, and no duplicate header is emitted.Added unit tests in
ContainerizationOCITestscovering the defaultUser-Agent, propagation of a customclientID, caller override, and coexistence with other headers. With the header omitted the new tests fail (the header reads as empty); with the fix they pass. Verified locally withswift test --filter RegistryRequestHeaderTests -Xswiftc -warnings-as-errors.Reported in apple/container#1583 (the registry client lives in this repository).