Skip to content

Commit

Permalink
Added layoutrenderer aspnet-request-has-body and aspnet-request-strea…
Browse files Browse the repository at this point in the history
…m-id (#845)
  • Loading branch information
bakgerman authored Aug 10, 2022
1 parent b19cfa1 commit f554128
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#if NET5_0_OR_GREATER
using NLog.LayoutRenderers;
using NLog.Web.Internal;
using System.Text;
using Microsoft.AspNetCore.Http.Features;

namespace NLog.Web.LayoutRenderers
{
/// <summary>
/// Used to indicate if the request has a body.
/// Uses IHttpRequestBodyDetectionFeature
///
/// This returns true when:
/// - It's an HTTP/1.x request with a non-zero Content-Length or a 'Transfer-Encoding: chunked' header.
/// - It's an HTTP/2 request that did not set the END_STREAM flag on the initial headers frame.
/// The final request body length may still be zero for the chunked or HTTP/2 scenarios.
///
/// This returns false when:
/// - It's an HTTP/1.x request with no Content-Length or 'Transfer-Encoding: chunked' header, or the Content-Length is 0.
/// - It's an HTTP/1.x request with Connection: Upgrade(e.g.WebSockets).
/// There is no HTTP request body for these requests and no data should be received until after the upgrade.
/// - It's an HTTP/2 request that set END_STREAM on the initial headers frame. When false, the request body should never return data.
/// </summary>
/// <remarks>
/// <code>${aspnet-request-has-body}</code>
/// </remarks>
[LayoutRenderer("aspnet-request-has-body")]
public class AspNetRequestHasBodyLayoutRenderer : AspNetLayoutRendererBase
{
/// <inheritdoc/>
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
var features = HttpContextAccessor.HttpContext.TryGetFeatureCollection();
var value = features?.Get<IHttpRequestBodyDetectionFeature>()?.CanHaveBody ?? false;
builder.Append(value ? '1' : '0');
}
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#if NET5_0_OR_GREATER
using System.Text;
using Microsoft.AspNetCore.Connections.Features;
using NLog.LayoutRenderers;
using NLog.Web.Internal;

namespace NLog.Web.LayoutRenderers
{
/// <summary>
/// Represents the long int identifier for the stream.
/// Uses IStreamIdFeature
///
/// This will inform when the connection is being reused, or when the connection has been closed and reopened,
/// based on when the value stays or same, or changes.
/// </summary>
/// <remarks>
/// <code>${aspnet-request-stream-id}</code>
/// </remarks>
[LayoutRenderer("aspnet-request-stream-id")]
public class AspNetRequestStreamIdLayoutRenderer : AspNetLayoutRendererBase
{
/// <inheritdoc/>
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
var features = HttpContextAccessor.HttpContext.TryGetFeatureCollection();
var streamIdFeature = features?.Get<IStreamIdFeature>();
builder.Append(streamIdFeature?.StreamId);
}
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#if NET5_0_OR_GREATER
using NLog.Web.LayoutRenderers;
using Microsoft.AspNetCore.Http.Features;
using NSubstitute;
using Xunit;

namespace NLog.Web.Tests.LayoutRenderers
{
public class AspNetRequestHasBodyLayoutRendererTests : LayoutRenderersTestBase<AspNetRequestHasBodyLayoutRenderer>
{
[Fact]
public void TrueTest()
{
// Arrange
var (renderer, httpContext) = CreateWithHttpContext();

var bodyDetectionFeature = Substitute.For<IHttpRequestBodyDetectionFeature>();
bodyDetectionFeature.CanHaveBody.Returns(true);

var featureCollection = new FeatureCollection();
featureCollection.Set<IHttpRequestBodyDetectionFeature>(bodyDetectionFeature);

httpContext.Features.Returns(featureCollection);
// Act
var result = renderer.Render(new LogEventInfo());
// Assert
Assert.Equal("1", result);
}

[Fact]
public void FalseTest()
{
// Arrange
var (renderer, httpContext) = CreateWithHttpContext();

var bodyDetectionFeature = Substitute.For<IHttpRequestBodyDetectionFeature>();
bodyDetectionFeature.CanHaveBody.Returns(false);

var featureCollection = new FeatureCollection();
featureCollection.Set<IHttpRequestBodyDetectionFeature>(bodyDetectionFeature);

httpContext.Features.Returns(featureCollection);
// Act
var result = renderer.Render(new LogEventInfo());
// Assert
Assert.Equal("0", result);
}

[Fact]
public void NullTest()
{
// Arrange
var (renderer, httpContext) = CreateWithHttpContext();

httpContext.Features.Returns(new FeatureCollection());
// Act
var result = renderer.Render(new LogEventInfo());
// Assert
Assert.Equal("0", result);
}

protected override void NullRendersEmptyString()
{
// Arrange
var (renderer, _) = CreateWithHttpContext();

// Act
string result = renderer.Render(LogEventInfo.CreateNullEvent());

// Assert
Assert.Equal("0", result);
}
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#if NET5_0_OR_GREATER
using NLog.Web.LayoutRenderers;
using Microsoft.AspNetCore.Connections.Features;
using Microsoft.AspNetCore.Http.Features;
using NSubstitute;
using Xunit;

namespace NLog.Web.Tests.LayoutRenderers
{
public class AspNetRequestStreamIdLayoutRendererTests : LayoutRenderersTestBase<AspNetRequestStreamIdLayoutRenderer>
{
[Fact]
public void SuccessTest()
{
// Arrange
var (renderer, httpContext) = CreateWithHttpContext();
var streamIdFeature = Substitute.For<IStreamIdFeature>();
streamIdFeature.StreamId.Returns(257);

var featureCollection = new FeatureCollection();
featureCollection.Set<IStreamIdFeature>(streamIdFeature);

httpContext.Features.Returns(featureCollection);
// Act
var result = renderer.Render(new LogEventInfo());
// Assert
Assert.Equal("257", result);
}

[Fact]
public void NullTest()
{
// Arrange
var (renderer, httpContext) = CreateWithHttpContext();
httpContext.Features.Returns(new FeatureCollection());
// Act
var result = renderer.Render(new LogEventInfo());
// Assert
Assert.Equal(string.Empty, result);
}

protected override void NullRendersEmptyString()
{
// Arrange
var (renderer, _) = CreateWithHttpContext();

// Act
string result = renderer.Render(LogEventInfo.CreateNullEvent());

// Assert
Assert.Equal("0", result);
}
}
}
#endif

0 comments on commit f554128

Please sign in to comment.