Skip to content

Commit

Permalink
NLogRequestPostedBodyMiddleware - Fixed handling of Stream.CanSeek
Browse files Browse the repository at this point in the history
  • Loading branch information
snakefoot committed Jun 30, 2023
1 parent 737ca2a commit 78b86bb
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 5 deletions.
10 changes: 8 additions & 2 deletions src/NLog.Web.AspNetCore/NLogRequestPostedBodyMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ private bool ShouldCaptureRequestBody(HttpContext context)
return false;
}

// If we cannot seek the stream we cannot capture the body
if (!postedBody.CanSeek)
if (postedBody.Position != 0 && !postedBody.CanSeek)
{
InternalLogger.Debug("NLogRequestPostedBodyMiddleware: HttpContext.Request.Body stream is non-seekable");
return false;
Expand All @@ -116,6 +115,13 @@ private bool ShouldCaptureRequestBody(HttpContext context)
/// <returns>The contents of the Stream read fully from start to end as a String</returns>
private static async Task<string> GetString(Stream stream)
{
// If we cannot seek the stream we cannot capture the body
if (!stream.CanSeek)
{
InternalLogger.Debug("NLogRequestPostedBodyMiddleware: HttpContext.Request.Body stream is non-seekable");
return string.Empty;
}

string responseText = null;

// Save away the original stream position
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public void EmptyBodyTest()
// Assert
Assert.NotNull(defaultContext.Items);
Assert.Empty(defaultContext.Items);
Assert.Null(defaultContext.Items[AspNetRequestPostedBodyLayoutRenderer.NLogPostedRequestBodyKey]);
}

[Fact]
Expand All @@ -86,7 +85,6 @@ public void ExcludContentTypeTest()
// Assert
Assert.NotNull(defaultContext.Items);
Assert.Empty(defaultContext.Items);
Assert.Null(defaultContext.Items[AspNetRequestPostedBodyLayoutRenderer.NLogPostedRequestBodyKey]);
}

[Fact]
Expand Down Expand Up @@ -204,17 +202,51 @@ public void CannotSeekLengthTest()
DefaultHttpContext defaultContext = new DefaultHttpContext();

defaultContext.Request.Body = Substitute.For<Stream>();
defaultContext.Request.ContentLength = 1;
defaultContext.Request.ContentLength = 2;
defaultContext.Request.ContentType = "text/plain";

defaultContext.Request.Body.CanRead.Returns(true);
defaultContext.Request.Body.CanSeek.Returns(false);
defaultContext.Request.Body.Length.Returns(2);
int firstCall = 2;
defaultContext.Request.Body.Read(default, default, default).ReturnsForAnyArgs(x => --firstCall);
defaultContext.Request.Body.ReadAsync(default, default, default).ReturnsForAnyArgs(x => --firstCall);

// Act
var middlewareInstance =
new NLogRequestPostedBodyMiddleware(Next,NLogRequestPostedBodyMiddlewareOptions.Default);
middlewareInstance.Invoke(defaultContext).ConfigureAwait(false).GetAwaiter().GetResult();

// Assert
Assert.NotNull(defaultContext.Items);
Assert.Single(defaultContext.Items);
Assert.NotNull(defaultContext.Items[AspNetRequestPostedBodyLayoutRenderer.NLogPostedRequestBodyKey]);
Assert.True(defaultContext.Items[AspNetRequestPostedBodyLayoutRenderer.NLogPostedRequestBodyKey] is string);
}

[Fact]
public void CannotSeekLengthAndStartedTest()
{
// Arrange
DefaultHttpContext defaultContext = new DefaultHttpContext();

defaultContext.Request.Body = Substitute.For<Stream>();
defaultContext.Request.ContentLength = 2;
defaultContext.Request.ContentType = "text/plain";

defaultContext.Request.Body.CanRead.Returns(true);
defaultContext.Request.Body.CanSeek.Returns(false);
defaultContext.Request.Body.Position.Returns(1); // Started
defaultContext.Request.Body.Length.Returns(2);
int firstCall = 2;
defaultContext.Request.Body.Read(default, default, default).ReturnsForAnyArgs(x => --firstCall);
defaultContext.Request.Body.ReadAsync(default, default, default).ReturnsForAnyArgs(x => --firstCall);

// Act
var middlewareInstance =
new NLogRequestPostedBodyMiddleware(Next, NLogRequestPostedBodyMiddlewareOptions.Default);
middlewareInstance.Invoke(defaultContext).ConfigureAwait(false).GetAwaiter().GetResult();

// Assert
Assert.NotNull(defaultContext.Items);
Assert.Empty(defaultContext.Items);
Expand Down

0 comments on commit 78b86bb

Please sign in to comment.