From 41ae5c6894bc88911c4f187318d8a0b92089aa6d Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Fri, 9 Feb 2024 16:05:00 -0800 Subject: [PATCH 1/3] Disable buffering of Blazor streaming responses --- .../src/RazorComponentEndpointInvoker.cs | 11 ++++++++++ .../StreamingRenderingTest.cs | 20 +++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs b/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs index 41efc89f9749..765c33c2d50c 100644 --- a/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs +++ b/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Components.Endpoints.Rendering; using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -116,6 +117,16 @@ await EndpointHtmlRenderer.InitializeStandardComponentServicesAsync( } } + if (!htmlContent.QuiescenceTask.IsCompleted) + { + // An incomplete QuiescenceTask indicates there may be streaming rendering updates. + // Disable all response buffering and compression on IIS like SignalR's ServerSentEventsServerTransport does. + var bufferingFeature = context.Features.GetRequiredFeature(); + bufferingFeature.DisableBuffering(); + + context.Response.Headers.ContentEncoding = "identity"; + } + // Importantly, we must not yield this thread (which holds exclusive access to the renderer sync context) // in between the first call to htmlContent.WriteTo and the point where we start listening for subsequent // streaming SSR batches (inside SendStreamingUpdatesAsync). Otherwise some other code might dispatch to the diff --git a/src/Components/test/E2ETest/ServerRenderingTests/StreamingRenderingTest.cs b/src/Components/test/E2ETest/ServerRenderingTests/StreamingRenderingTest.cs index ddd8ff262230..9e11d5330854 100644 --- a/src/Components/test/E2ETest/ServerRenderingTests/StreamingRenderingTest.cs +++ b/src/Components/test/E2ETest/ServerRenderingTests/StreamingRenderingTest.cs @@ -3,13 +3,13 @@ using System.Globalization; using System.Net.Http; -using System.Net.Http.Headers; using System.Text; using System.Text.RegularExpressions; using Components.TestServer.RazorComponents; using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; using Microsoft.AspNetCore.E2ETesting; +using Microsoft.Net.Http.Headers; using OpenQA.Selenium; using TestServer; using Xunit.Abstractions; @@ -30,13 +30,29 @@ public override Task InitializeAsync() => InitializeAsync(BrowserFixture.StreamingContext); [Fact] - public void CanRenderNonstreamingPageWithoutInjectingStreamingMarkers() + public async Task CanRenderNonstreamingPageWithoutInjectingStreamingMarkersOrHeaders() { Navigate(ServerPathBase); Browser.Equal("Hello", () => Browser.Exists(By.TagName("h1")).Text); Assert.DoesNotContain(" Date: Fri, 9 Feb 2024 16:45:21 -0800 Subject: [PATCH 2/3] Update src/Components/test/E2ETest/ServerRenderingTests/StreamingRenderingTest.cs --- .../test/E2ETest/ServerRenderingTests/StreamingRenderingTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/test/E2ETest/ServerRenderingTests/StreamingRenderingTest.cs b/src/Components/test/E2ETest/ServerRenderingTests/StreamingRenderingTest.cs index 9e11d5330854..76ba4abec238 100644 --- a/src/Components/test/E2ETest/ServerRenderingTests/StreamingRenderingTest.cs +++ b/src/Components/test/E2ETest/ServerRenderingTests/StreamingRenderingTest.cs @@ -52,7 +52,7 @@ public async Task DoesRenderStreamingPageWithStreamingHeadersToDisableBuffering( using var response = await httpClient.GetAsync(new Uri(_serverFixture.RootUri, $"{ServerPathBase}/streaming"), HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); - Assert.Equal("identity2", response.Content.Headers.ContentEncoding.Single()); + Assert.Equal("identity", response.Content.Headers.ContentEncoding.Single()); } [Theory] From d588635c0c644f0593c8e924b0a1e7aaf3636ddd Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Mon, 12 Feb 2024 12:53:30 -0800 Subject: [PATCH 3/3] Update src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs Co-authored-by: Mackinnon Buck --- src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs b/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs index 765c33c2d50c..02bf4e3a3467 100644 --- a/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs +++ b/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs @@ -117,7 +117,7 @@ await EndpointHtmlRenderer.InitializeStandardComponentServicesAsync( } } - if (!htmlContent.QuiescenceTask.IsCompleted) + if (!quiesceTask.IsCompleted) { // An incomplete QuiescenceTask indicates there may be streaming rendering updates. // Disable all response buffering and compression on IIS like SignalR's ServerSentEventsServerTransport does.