feat: send OS context headers on update check requests#52
Open
ranganath42 wants to merge 10 commits into
Open
Conversation
The updater now sends X-OS-Type, X-OS-Version and X-OS-Arch with every update check, giving the update server the context to select a build compatible with this host. X-OS-Type and X-OS-Arch carry runtime.GOOS and runtime.GOARCH verbatim, so no OS/arch mapping code ships in the client; the server owns the vocabulary. X-OS-Version is best effort and omitted if detection fails: - Windows: RtlGetVersion (major.minor.build, unaffected by compatibility shims) - macOS: sysctl kern.osproductversion - Linux: kernel release via uname
| req.Header.Set(headerOSTypeKey, runtime.GOOS) | ||
| req.Header.Set(headerOSArchKey, runtime.GOARCH) | ||
| // Best effort: an unknown OS version is better than a failed update check. | ||
| if version, err := osVersion(); err == nil && version != "" { |
There was a problem hiding this comment.
nit: shouldn't we log the error here?
priyankasuduge
approved these changes
Jul 6, 2026
hiroxy
reviewed
Jul 6, 2026
| // SILVER - Service Wrapper | ||
| // Auto Updater | ||
| // | ||
| // Copyright (c) 2014-2021 PaperCut Software http://www.papercut.com/ |
| // See the project's LICENSE file for more information. | ||
| // | ||
|
|
||
| package update |
| // addOSContextToRequestHeader adds OS identity headers used by the update | ||
| // server to select a build compatible with this host. GOOS and GOARCH are | ||
| // sent verbatim so no OS/arch mapping code ships in the client. | ||
| func addOSContextToRequestHeader(req *http.Request) { |
Contributor
There was a problem hiding this comment.
"set" might be better than "add" because the header values are set rather than added. Also, ToRequestHeader could be removed from the function name. It is already indicated by the parameter type.
How about, for example, setPlatformHeaders or setOSHeaders?
| req.Header.Set(headerOSTypeKey, runtime.GOOS) | ||
| req.Header.Set(headerOSArchKey, runtime.GOARCH) | ||
| // Best effort: an unknown OS version is better than a failed update check. | ||
| if version, err := osVersion(); err == nil && version != "" { |
Contributor
There was a problem hiding this comment.
osVersion shouldn't return an empty version if it returns a nil error.
| // See the project's LICENSE file for more information. | ||
| // | ||
|
|
||
| //go:build darwin |
| // osVersion is unknown on unsupported platforms; the X-OS-Version header is | ||
| // simply omitted. | ||
| func osVersion() (string, error) { | ||
| return "", nil |
Contributor
There was a problem hiding this comment.
Returning an error, such as "unsupported OS", would be better.
| // See the project's LICENSE file for more information. | ||
| // | ||
|
|
||
| //go:build windows |
| // SILVER - Service Wrapper | ||
| // Auto Updater | ||
| // | ||
| // Copyright (c) 2014-2021 PaperCut Software http://www.papercut.com/ |
| // SILVER - Service Wrapper | ||
| // Auto Updater | ||
| // | ||
| // Copyright (c) 2014-2021 PaperCut Software http://www.papercut.com/ |
added 9 commits
July 6, 2026 16:14
X-OS-Arch reports runtime.GOARCH, the architecture of the running binary, which under emulation differs from the host: an x64 build under Rosetta 2 or Windows-on-ARM reports amd64 on an arm64 machine. X-OS-Native-Arch reports the host architecture so the update server can distinguish hosts that could run a native build from hosts that cannot (e.g. genuine Intel Macs vs M1 Macs still on the x64 build). Detection is best effort with runtime.GOARCH as the fallback: - macOS: sysctl.proc_translated (1 under Rosetta 2) - Windows: IsWow64Process2 native machine (Windows 10 1511+; older hosts cannot be ARM64 machines, so the fallback is correct there) - others: assumed equal to the binary architecture
The _darwin/_windows/_linux filename suffixes already constrain these files; only the _other files need explicit tags.
An empty string with a nil error was a silent sentinel; the caller already omits the X-OS-Version header on error, so behavior is unchanged.
uname's release string carries distro suffixes on most distributions (5.15.0-91-generic, 4.18.0-477.10.1.el8_8.x86_64) which would break the update server's segment-by-segment numeric version comparison. Trim to the leading dot-separated numeric part so X-OS-Version is always comparable (5.15.0-91-generic → 5.15.0). Windows and macOS are unaffected; their sources are numeric by construction.
osVersion now guarantees a non-empty version on nil error: linux returns an error for a kernel release with no numeric prefix, darwin for an empty sysctl value, and windows is numeric by construction. The caller drops its empty-string check accordingly.
Set describes Header.Set semantics; the parameter type already says it operates on a request.
Black-box tests via an export_test.go bridge; header names are asserted as literal wire strings rather than the package constants.
Matches the updater's existing best-effort convention (see addIDProfileToRequestHeader): print the error and continue, so an omitted X-OS-Version header is diagnosable in the field.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The updater now sends X-OS-Type, X-OS-Version and X-OS-Arch with every update check, giving the update server the context to select a build compatible with this host.
X-OS-Type and X-OS-Arch carry runtime.GOOS and runtime.GOARCH verbatim, so no OS/arch mapping code ships in the client; the server owns the vocabulary.
X-OS-Version is best effort and omitted if detection fails: