Add support for crendential helpers to replace default headers
- Dominant language
- Java
- Stars
- 25.8k
- Forks
- 4.6k
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 72
Description
### Description of the feature request:
Credential helpers can be used to not only provide authentication information but also as a workaround for requests which need to define specific headers to succeed. The headers from the credential helper output are added to an `HttpRequest` which is already initialised with default values (constructed [here](https://github.com/bazelbuild/bazel/blob/ae3262f1450d44fcbb1d8646b2ffac685541a0de/src/main/java/com/google/devtools/build/lib/remote/http/HttpDownloadHandler.java#L177)).
If a credential helper emits a non-authorisation header with an identifier which matches one already in the default `HttpRequest` it adds it alongside the existing header matching that identifier, rather than replacing it ([here](https://github.com/bazelbuild/bazel/blob/88ed1bcf178646239bdaf590c3e74c0f55cfcc35/src/main/java/com/google/devtools/build/lib/remote/http/AbstractHttpHandler.java#L80)). This means that if any of these default headers elicit an undesirable response, there's no way to replace them.
Would it be possible to have some method for credential helpers to *replace* headers instead of add them?
### Which category does this issue belong to?
Core
### What underlying problem are you trying to solve with this feature?
To use a release asset in a private Github repository as a source for a Bazel registry module a request needs to be made to the Github [API](https://docs.github.com/en/rest/releases/assets?apiVersion=2022-11-28#get-a-release-asset). As the repository is private this requires setting the `Authorization` header. In addition to this the `Accept` header must be set to `application/octet-stream` to retrieve the actual asset as opposed to JSON with information about the asset.
The [default](https://github.com/bazelbuild/bazel/blob/ae3262f1450d44fcbb1d8646b2ffac685541a0de/src/main/java/com/google/devtools/build/lib/remote/http/HttpDownloadHandler.java#L182) `HttpRequest` sets `Accept: */*`, rendering a credential helper setting `Accept: application/octet-stream` pointless. It seems that the Github API given the choice of being able to return any MIME type it will pick a default of providing the JSON with information about the asset instead of the asset itself.
This means there's currently no means (to my knowledge), of using a private Github asset as a source for a Bazel registry module or any Bazel http repository rules.
### Which operating system are you running Bazel on?
Windows/Linux/Mac
### What is the output of `bazel info release`?
release 7.1.1
### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.
_No response_
### What's the output of `git remote get-url origin; git rev-parse HEAD` ?
_No response_
### Have you found anything relevant by searching the web?
_No response_
### Any other information, logs, or outputs that you want to share?
_No response_
Contributor guide
Research direction
Start with the default HttpRequest construction in src/main/java/com/google/devtools/build/lib/remote/http/HttpDownloadHandler.java and the credential-header handling in AbstractHttpHandler.java. Trace how matching headers are merged, then determine how completion should allow a credential helper to replace a default such as Accept so a private GitHub release asset can be retrieved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github, java
- Domain
- authentication, networking
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100