Skip to content

feat(updater): support custom HTTP headers via updater.conf - #54

Open
ranganath42 wants to merge 3 commits into
masterfrom
feat/custom-headers-via-file
Open

feat(updater): support custom HTTP headers via updater.conf#54
ranganath42 wants to merge 3 commits into
masterfrom
feat/custom-headers-via-file

Conversation

@ranganath42

@ranganath42 ranganath42 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Custom HTTP headers via updater.conf

Adds an optional updater.conf file next to the updater binary, letting operators attach custom HTTP headers (tenant IDs, routing tags, etc.) to update checks and downloads. No code changes needed per deployment.

  • New Headers JSON config, fails open if missing or invalid.
  • Validated against RFC 9110. Capped at 4 KB per value, 20 headers, 64 KB file size.
  • Overrides the deprecated updater-profile.conf headers on collision, but cannot override headers describing the binary/host itself (User-Agent, OS headers, hop-by-hop headers).
  • Download now builds a real request (previously plain http.Get, no headers, no error status check).
  • Tests for validation, capping, file loading, and download error handling.

Comment thread updater/update/update.go Outdated
return nil, err
}
req.Header.Set("User-Agent", userAgent())
// Legacy updater-profile.conf headers are set first so that

@ranganath42 ranganath42 Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, the header priority is enforced purely by call order.
Reviewers, do you think we should make it a bit more robust by introducing a merge function instead of relying on order? Not trivial, but not a lot of rewrok either.

@ranganath42
ranganath42 marked this pull request as ready for review July 24, 2026 11:13
@ranganath42
ranganath42 force-pushed the feat/custom-headers-via-file branch from e9ab958 to f19a98f Compare July 24, 2026 11:59
Comment thread updater/update/headers.go Outdated
// Go's net/http manages these itself and ignores whatever is set on
// req.Header for them. Allowing them through would silently do nothing,
// which is a confusing trap for an operator configuring updater.conf.
var systemHeaderKeys = map[string]bool{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

map[string]struct{}

Comment thread updater/update/headers.go

const (
headersFileName = "updater.conf"
maxHeadersFileBytes = 64 * 1024

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume these limits are intended to restrict the header size.

If such a restriction is to be implemented, I think it should either limit only the data size of the JSON file, or, instead of the file size limitation, calculate the number of headers, the size of keys and values when decoding the JSON.

If restrictions are applied to both, there is a possibility that a definition cannot be established because it fails to meet one of the restrictions. Wouldn't that cause confusion for users defining custom headers?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Want me to drop the per-value/per-count limits and keep only the file-size limit?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Envoy proxy does something similar.
It enforces hard byte-size limits (max_request_headers_kb) and max header counts (max_headers_count).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the new configuration file is used for other purposes as well, it may be difficult in the future to manage the size of custom headers using only the configuration file size. If flexibility is required, calculating the custom header size with low-level parsing of JSON data will be required.

Comment thread updater/update/headers.go Outdated
func AddCustomHeaders(req *http.Request) {
headers, err := loadCustomHeaders()
if err != nil {
if os.IsNotExist(err) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

erros.Is should be used.

Comment thread updater/update/headers.go Outdated
// headerFieldNameRE matches a non-empty RFC 9110 token.
// That's the valid form for an HTTP field-name.
// See https://www.rfc-editor.org/rfc/rfc9110.html#section-5.6.2
var headerFieldNameRE = regexp.MustCompile(`^[A-Za-z0-9!#$%&'*+\-.^_` + "`" + `|~]+$`)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to use "re" as a prefix like ErrSomething.
Also, it would be written using either of the following methods

regexp.MustCompile(`^[\w!#$%&'*+\-.^` + "`" + `|~]+$`)
regexp.MustCompile("^[\\w!#$%&'*+\\-.^`|~]+$")

Comment thread updater/update/headers.go
// See the project's LICENSE file for more information.
//

package update

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to split into an internal pacakge, such as update/internal/customheaer.

Comment thread updater/update/headers.go

const (
headersFileName = "updater.conf"
maxHeadersFileBytes = 64 * 1024

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the new configuration file is used for other purposes as well, it may be difficult in the future to manage the size of custom headers using only the configuration file size. If flexibility is required, calculating the custom header size with low-level parsing of JSON data will be required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants