diff --git a/src/Middleware/Spa/SpaProxy/src/SpaProxyLaunchManager.cs b/src/Middleware/Spa/SpaProxy/src/SpaProxyLaunchManager.cs index 325b133acbd3..f7a7847caa59 100644 --- a/src/Middleware/Spa/SpaProxy/src/SpaProxyLaunchManager.cs +++ b/src/Middleware/Spa/SpaProxy/src/SpaProxyLaunchManager.cs @@ -33,14 +33,6 @@ public SpaProxyLaunchManager( public void StartInBackground(CancellationToken cancellationToken) { - var httpClient = new HttpClient(new HttpClientHandler() - { - // It's ok for us to do this here since this service is only plugged in during development. - ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator - }); - // Certain frontend build tools rely on the the ACCEPT Header being set, otherwise these tools - // might be unable to perform their client-side fallback logic. - httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*")); _logger.LogInformation($"No SPA development server running at {_options.ServerUrl} found."); // We are not waiting for the SPA proxy to launch, instead we are going to rely on a piece of @@ -53,7 +45,7 @@ public void StartInBackground(CancellationToken cancellationToken) { if (_launchTask == null) { - _launchTask = UpdateStatus(StartSpaProcessAndProbeForLiveness(httpClient, cancellationToken)); + _launchTask = UpdateStatus(StartSpaProcessAndProbeForLiveness(cancellationToken)); } } @@ -79,11 +71,7 @@ async Task UpdateStatus(Task launchTask) public async Task IsSpaProxyRunning(CancellationToken cancellationToken) { - var httpClient = new HttpClient(new HttpClientHandler() - { - // It's ok for us to do this here since this service is only plugged in during development. - ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator - }); + var httpClient = CreateHttpClient(); using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10)); using var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, cancellationToken); @@ -102,6 +90,18 @@ exception is TaskCanceledException || } } + private static HttpClient CreateHttpClient() + { + var httpClient = new HttpClient(new HttpClientHandler() + { + // It's ok for us to do this here since this service is only plugged in during development. + ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator + }); + // We don't care about the returned content type as long as the server is able to answer with 2XX + httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*", 0.1)); + return httpClient; + } + private async Task ProbeSpaDevelopmentServerUrl(HttpClient httpClient, CancellationToken cancellationToken) { using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10)); @@ -121,12 +121,13 @@ exception is TaskCanceledException || } } - private async Task StartSpaProcessAndProbeForLiveness(HttpClient httpClient, CancellationToken cancellationToken) + private async Task StartSpaProcessAndProbeForLiveness(CancellationToken cancellationToken) { LaunchDevelopmentProxy(); var sw = Stopwatch.StartNew(); var livenessProbeSucceeded = false; var maxTimeoutReached = false; + var httpClient = CreateHttpClient(); while (_spaProcess != null && !_spaProcess.HasExited && !maxTimeoutReached) { livenessProbeSucceeded = await ProbeSpaDevelopmentServerUrl(httpClient, cancellationToken);