feat(launcher): complete Campaign LA11 pre-gate support

This commit is contained in:
Erik 2026-08-15 00:02:04 +02:00
parent f881e5b467
commit 134edabed2
19 changed files with 433 additions and 55 deletions

View file

@ -11,8 +11,9 @@ public interface IReleaseManifestClient
/// <summary>
/// Strict, bounded reader for the pinned GitHub Releases manifest. Production
/// construction is HTTPS-only. The loopback HTTP allowance is available only
/// through an internal fixture factory and is never inferred from a URI.
/// construction is pinned and HTTPS-only. The explicitly named process-local
/// feed factory independently revalidates its URI and can admit HTTP only for
/// the loopback operator fixture; it cannot change the production constructor.
/// Redirects are followed manually so every hop is checked before any bytes
/// cross that hop.
/// </summary>
@ -74,6 +75,49 @@ public sealed class ReleaseManifestClient : IReleaseManifestClient, IDisposable
CreateRedirectDisabledHandler(),
timeout);
/// <summary>
/// Creates the explicit process-local feed seam used by the Campaign LA
/// isolated operator fixture. HTTPS stays HTTPS-only. HTTP is admitted
/// only for a loopback manifest, and never by the pinned production
/// constructor. Credential-bearing or mutable URI suffixes are rejected.
/// </summary>
public static ReleaseManifestClient CreateLocalUpdateFeedOverride(
Uri manifestUri,
TimeSpan? timeout = null)
{
ArgumentNullException.ThrowIfNull(manifestUri);
if (!string.IsNullOrEmpty(manifestUri.UserInfo)
|| !string.IsNullOrEmpty(manifestUri.Query)
|| !string.IsNullOrEmpty(manifestUri.Fragment))
{
throw new LauncherUpdateException(
"A process-local manifest URI cannot contain user information, "
+ "a query, or a fragment.");
}
bool allowLoopbackHttp = string.Equals(
manifestUri.Scheme,
Uri.UriSchemeHttp,
StringComparison.Ordinal)
&& manifestUri.IsLoopback;
if (!string.Equals(
manifestUri.Scheme,
Uri.UriSchemeHttps,
StringComparison.Ordinal)
&& !allowLoopbackHttp)
{
throw new LauncherUpdateException(
"A process-local manifest URI must use HTTPS "
+ "(loopback HTTP is fixture-only).");
}
return new ReleaseManifestClient(
manifestUri,
allowLoopbackHttp,
CreateRedirectDisabledHandler(),
timeout);
}
internal static ReleaseManifestClient CreateForTransportTest(
Uri manifestUri,
bool allowLoopbackHttp,