Disable response buffering via the IHttpBufferingFeature (#379)
* Disable response buffering via the IHttpBufferingFeature - To make sure SignalR works with servers and middleware that do perform response buffering, disable it via the IHttpBufferingFeature for SSE. - Added test to verify buffering is disabled
This commit is contained in:
parent
4c183b4d00
commit
0546dc21f4
|
|
@ -9,6 +9,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks.Channels;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Sockets.Internal.Formatters;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
|
|
@ -29,6 +30,11 @@ namespace Microsoft.AspNetCore.Sockets.Transports
|
|||
{
|
||||
context.Response.ContentType = "text/event-stream";
|
||||
context.Response.Headers["Cache-Control"] = "no-cache";
|
||||
|
||||
// Make sure we disable all response buffering for SSE
|
||||
var bufferingFeature = context.Features.Get<IHttpBufferingFeature>();
|
||||
bufferingFeature?.DisableResponseBuffering();
|
||||
|
||||
context.Response.Headers["Content-Encoding"] = "identity";
|
||||
|
||||
await context.Response.Body.FlushAsync();
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks.Channels;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Sockets.Transports;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
|
@ -30,6 +32,22 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
|||
Assert.Equal("no-cache", context.Response.Headers["Cache-Control"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SSETurnsResponseBufferingOff()
|
||||
{
|
||||
var channel = Channel.CreateUnbounded<Message>();
|
||||
var context = new DefaultHttpContext();
|
||||
var feature = new HttpBufferingFeature();
|
||||
context.Features.Set<IHttpBufferingFeature>(feature);
|
||||
var sse = new ServerSentEventsTransport(channel, new LoggerFactory());
|
||||
|
||||
Assert.True(channel.Out.TryComplete());
|
||||
|
||||
await sse.ProcessRequestAsync(context, context.RequestAborted);
|
||||
|
||||
Assert.True(feature.ResponseBufferingDisabled);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Hello World", "data: T\r\ndata: Hello World\r\n\r\n")]
|
||||
[InlineData("Hello\nWorld", "data: T\r\ndata: Hello\r\ndata: World\r\n\r\n")]
|
||||
|
|
@ -53,5 +71,22 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
|||
|
||||
Assert.Equal(expected, Encoding.UTF8.GetString(ms.ToArray()));
|
||||
}
|
||||
|
||||
private class HttpBufferingFeature : IHttpBufferingFeature
|
||||
{
|
||||
public bool RequestBufferingDisabled { get; set; }
|
||||
|
||||
public bool ResponseBufferingDisabled { get; set; }
|
||||
|
||||
public void DisableRequestBuffering()
|
||||
{
|
||||
RequestBufferingDisabled = true;
|
||||
}
|
||||
|
||||
public void DisableResponseBuffering()
|
||||
{
|
||||
ResponseBufferingDisabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue