Skip to content

Send a valid User-Agent when the app name is not an HTTP token [patch] - #200

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/195-user-agent-product-name
Oct 9, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/195-user-agent-product-name

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #195

What changed

GitHubProvider.CreateClient() passed AppDomain.CurrentDomain.FriendlyName straight to Octokit's ProductHeaderValue. If the host's entry assembly name isn't an HTTP token (for example My App or Tool (x86)), every GitHubProvider call threw FormatException before sending a request, and the exception escaped the GitHostingException hierarchy.

  • GitIntegration/GitHubProvider.cs:
    • Added ToProductName(string?). It replaces every character outside the RFC 9110 token set, including non-ASCII letters, with - and trims leading and trailing dashes. If nothing usable is left, it falls back to ktsu.GitIntegration. The host's name still shows in GitHub's logs whenever any of it is usable.
    • Added an internal ApplicationName init property, defaulting to FriendlyName. It lets tests drive names the test host never has; under MSTest the host's name is always testhost.
  • GitIntegration.Test/Hosting/GitHubProviderTests.cs:
    • A data-driven test runs GetRepositoriesAsync through FakeHttpMessageHandler with My App, Tool (x86), a/b@c, Café, testhost and ktsu.Tool_1. It asserts that the request is sent and checks the product name in the User-Agent.
    • A second test covers the fallback for a null, empty, whitespace-only or entirely non-ASCII name.

AzureDevOpsProvider sets no User-Agent from the app name, so only the GitHub provider needed the change.

Verification

  • With the sanitising reverted (new(ApplicationName)), the four non-token cases fail with the exception from the issue: System.FormatException: The format of value 'My App' is invalid. With the fix, they pass.
  • Full suite on Linux (.NET 10): 774 passed, 0 failed.
  • The Release build of the library for net10.0 and net9.0 has 0 warnings and 0 errors.

🤖 Generated with Claude Code

https://claude.ai/code/session_016n29aex51pHZeVj2vx831E


Generated by Claude Code

GitHubProvider built Octokit's ProductHeaderValue straight from
AppDomain.FriendlyName, so a host built from "My App.csproj" threw
FormatException from every call before a request was sent, outside the
GitHostingException hierarchy. Replace characters outside the RFC 9110
token set with '-', fall back to "ktsu.GitIntegration" when nothing usable
is left, and test it through the fake transport with names the test host
itself never has.

Fixes #195

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016n29aex51pHZeVj2vx831E
@sonarqubecloud

sonarqubecloud Bot commented Oct 9, 2026

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 1c9f011 into main Oct 9, 2026
16 checks passed
@matt-edmondson
matt-edmondson deleted the fix/195-user-agent-product-name branch October 9, 2026 01:14
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.

Every GitHubProvider call throws FormatException when the host app's name contains a space or other non-token character

2 participants