Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ private async Task BufferResponseStreamAsync(HttpContextCore context, BufferResp

var responseBodyFeature = context.Features.GetRequired<IHttpResponseBodyFeature>();

await using var bufferedFeature = new HttpRequestAdapterFeature(responseBodyFeature, metadata);
await using var bufferedFeature = new HttpResponseAdapterFeature(responseBodyFeature, metadata);

context.Features.Set<IHttpResponseBodyFeature>(bufferedFeature);
context.Features.Set<IHttpRequestAdapterFeature>(bufferedFeature);
context.Features.Set<IHttpResponseAdapterFeature>(bufferedFeature);

try
{
Expand All @@ -46,7 +46,7 @@ private async Task BufferResponseStreamAsync(HttpContextCore context, BufferResp
finally
{
context.Features.Set(responseBodyFeature);
context.Features.Set<IHttpRequestAdapterFeature>(null);
context.Features.Set<IHttpResponseAdapterFeature>(null);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
namespace Microsoft.AspNetCore.SystemWebAdapters;

/// <summary>
/// This feature implements the <see cref="IHttpRequestAdapterFeature"/> to expose functionality for the adapters. As part of that,
/// This feature implements the <see cref="IHttpResponseAdapterFeature"/> to expose functionality for the adapters. As part of that,
/// it overrides the following features as well:
///
/// <list>
Expand All @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.SystemWebAdapters;
/// </item>
/// </list>
/// </summary>
internal class HttpRequestAdapterFeature : Stream, IHttpResponseBodyFeature, IHttpRequestAdapterFeature
internal class HttpResponseAdapterFeature : Stream, IHttpResponseBodyFeature, IHttpResponseAdapterFeature
{
private enum StreamState
{
Expand All @@ -40,7 +40,7 @@ private enum StreamState
private bool _suppressContent;
private StreamState _state;

public HttpRequestAdapterFeature(IHttpResponseBodyFeature httpResponseBody, BufferResponseStreamAttribute metadata)
public HttpResponseAdapterFeature(IHttpResponseBodyFeature httpResponseBody, BufferResponseStreamAttribute metadata)
{
_responseBodyFeature = httpResponseBody;
_metadata = metadata;
Expand Down Expand Up @@ -73,17 +73,17 @@ Task IHttpResponseBodyFeature.StartAsync(CancellationToken cancellationToken)

PipeWriter IHttpResponseBodyFeature.Writer => _pipeWriter ??= PipeWriter.Create(this, new StreamPipeWriterOptions(leaveOpen: true));

bool IHttpRequestAdapterFeature.SuppressContent
bool IHttpResponseAdapterFeature.SuppressContent
{
get => _suppressContent;
set => _suppressContent = value;
}

Task IHttpRequestAdapterFeature.EndAsync() => CompleteAsync();
Task IHttpResponseAdapterFeature.EndAsync() => CompleteAsync();

bool IHttpRequestAdapterFeature.IsEnded => _state == StreamState.Complete;
bool IHttpResponseAdapterFeature.IsEnded => _state == StreamState.Complete;

void IHttpRequestAdapterFeature.ClearContent()
void IHttpResponseAdapterFeature.ClearContent()
{
if (_bufferedStream is not null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public ResponseEndFilter(ILogger<ResponseEndFilter> logger)

public void OnActionExecuted(ActionExecutedContext context)
{
if (context.Result is not null && context.HttpContext.Features.Get<IHttpRequestAdapterFeature>() is { IsEnded: true })
if (context.Result is not null && context.HttpContext.Features.Get<IHttpResponseAdapterFeature>() is { IsEnded: true })
{
LogClearingResult();
context.Result = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Microsoft.AspNetCore.SystemWebAdapters;

internal interface IHttpRequestAdapterFeature
internal interface IHttpResponseAdapterFeature
{
bool IsEnded { get; }

Expand Down
6 changes: 3 additions & 3 deletions src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@ public class HttpResponse

private NameValueCollection? _headers;
private ResponseHeaders? _typedHeaders;
private IHttpRequestAdapterFeature? _adapterFeature;
private FeatureReference<IHttpResponseAdapterFeature> _adapterFeature;
private TextWriter? _writer;
private HttpCookieCollection? _cookies;

internal HttpResponse(HttpResponseCore response)
{
_response = response;
_adapterFeature = FeatureReference<IHttpResponseAdapterFeature>.Default;
}

private IHttpRequestAdapterFeature AdapterFeature => _adapterFeature ??= _response.HttpContext.Features.Get<IHttpRequestAdapterFeature>()
?? throw new InvalidOperationException($"Response buffering must be enabled on this endpoint for this API via the BufferResponseStreamAttribute metadata item");
private IHttpResponseAdapterFeature AdapterFeature => _adapterFeature.Fetch(_response.HttpContext.Features) ?? throw new InvalidOperationException($"Response buffering must be enabled on this endpoint for this API via the BufferResponseStreamAttribute metadata item");

internal ResponseHeaders TypedHeaders => _typedHeaders ??= new(_response.Headers);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@ public void TrySkipIisCustomErrors(bool isEnabled)
public void SuppressContent(bool suppressContent)
{
// Arrange
var feature = new Mock<IHttpRequestAdapterFeature>();
var feature = new Mock<IHttpResponseAdapterFeature>();
feature.SetupProperty(f => f.SuppressContent);

var features = new Mock<IFeatureCollection>();
features.Setup(f => f.Get<IHttpRequestAdapterFeature>()).Returns(feature.Object);
features.Setup(f => f[typeof(IHttpResponseAdapterFeature)]).Returns(feature.Object);

var context = new Mock<HttpContextCore>();
context.Setup(c => c.Features).Returns(features.Object);
Expand All @@ -133,10 +133,10 @@ public void SuppressContent(bool suppressContent)
public void End()
{
// Arrange
var feature = new Mock<IHttpRequestAdapterFeature>();
var feature = new Mock<IHttpResponseAdapterFeature>();

var features = new Mock<IFeatureCollection>();
features.Setup(f => f.Get<IHttpRequestAdapterFeature>()).Returns(feature.Object);
features.Setup(f => f[typeof(IHttpResponseAdapterFeature)]).Returns(feature.Object);

var context = new Mock<HttpContextCore>();
context.Setup(c => c.Features).Returns(features.Object);
Expand Down Expand Up @@ -258,11 +258,11 @@ public void Clear()
{ HeaderNames.ContentType, "application/json" },
};

var feature = new Mock<IHttpRequestAdapterFeature>();
var feature = new Mock<IHttpResponseAdapterFeature>();
var responseFeature = new Mock<IHttpResponseFeature>();

var features = new Mock<IFeatureCollection>();
features.Setup(f => f.Get<IHttpRequestAdapterFeature>()).Returns(feature.Object);
features.Setup(f => f[typeof(IHttpResponseAdapterFeature)]).Returns(feature.Object);
features.Setup(f => f.Get<IHttpResponseFeature>()).Returns(responseFeature.Object);

var body = new Mock<Stream>();
Expand Down Expand Up @@ -290,11 +290,11 @@ public void Clear()
public void ClearContentsStreamNotSeekable()
{
// Arrange
var feature = new Mock<IHttpRequestAdapterFeature>();
var feature = new Mock<IHttpResponseAdapterFeature>();
var body = new Mock<Stream>();

var features = new Mock<IFeatureCollection>();
features.Setup(f => f.Get<IHttpRequestAdapterFeature>()).Returns(feature.Object);
features.Setup(f => f[typeof(IHttpResponseAdapterFeature)]).Returns(feature.Object);

var context = new Mock<HttpContextCore>();
context.Setup(c => c.Features).Returns(features.Object);
Expand Down Expand Up @@ -490,7 +490,7 @@ public void RedirectPermanent(bool? endResponse)
var url = _fixture.Create<string>();
var features = new FeatureCollection();

var bufferedBody = new Mock<IHttpRequestAdapterFeature>();
var bufferedBody = new Mock<IHttpResponseAdapterFeature>();
bufferedBody.SetupAllProperties();
features.Set(bufferedBody.Object);

Expand Down