Skip to content

Commit e22d5aa

Browse files
committed
test: RequestBodyExtractionDispatcher
1 parent 79b6563 commit e22d5aa

File tree

7 files changed

+130
-35
lines changed

7 files changed

+130
-35
lines changed

src/Sentry.AspNetCore/SentryAspNetCoreOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public bool IncludeRequestPayload
2121
{
2222
get => MaxRequestBodySize != RequestSize.None;
2323
// As originally there was no truncation, setting to Large.
24-
set => MaxRequestBodySize = value ? RequestSize.Large : RequestSize.None;
24+
set => MaxRequestBodySize = value ? RequestSize.Always : RequestSize.None;
2525
}
2626

2727
/// <summary>

src/Sentry/Extensibility/DiagnosticLoggerExtensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ public static void LogWarning<TArg>(
5353
TArg arg)
5454
=> logger.LogIfEnabled(SentryLevel.Warning, message, arg);
5555

56+
public static void LogWarning<TArg, TArg2>(
57+
this IDiagnosticLogger logger,
58+
string message,
59+
TArg arg,
60+
TArg2 arg2)
61+
=> logger.LogIfEnabled(SentryLevel.Warning, message, arg, arg2);
62+
5663
public static void LogError(
5764
this IDiagnosticLogger logger,
5865
string message,

src/Sentry/Extensibility/RequestBodyExtractionDispatcher.cs

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23

34
namespace Sentry.Extensibility
@@ -11,8 +12,8 @@ public class RequestBodyExtractionDispatcher : IRequestPayloadExtractor
1112

1213
public RequestBodyExtractionDispatcher(IEnumerable<IRequestPayloadExtractor> extractors, SentryOptions options, RequestSize size)
1314
{
14-
Extractors = extractors;
15-
_options = options;
15+
Extractors = extractors ?? throw new ArgumentNullException(nameof(extractors));
16+
_options = options ?? throw new ArgumentNullException(nameof(options));
1617
_size = size;
1718
}
1819

@@ -23,47 +24,38 @@ public object ExtractPayload(IHttpRequest request)
2324
return null;
2425
}
2526

26-
var extractRequestBody = false;
2727
switch (_size)
2828
{
2929
case RequestSize.Small when request.ContentLength < 1_000:
30-
extractRequestBody = true;
31-
break;
3230
case RequestSize.Medium when request.ContentLength < 10_000:
33-
extractRequestBody = true;
34-
break;
35-
case RequestSize.Large:
36-
extractRequestBody = true;
31+
case RequestSize.Always:
32+
_options.DiagnosticLogger.LogDebug("Attempting to read request body of size: {0}, configured max: {1}.",
33+
request.ContentLength, _size);
34+
35+
foreach (var extractor in Extractors)
36+
{
37+
var data = extractor.ExtractPayload(request);
38+
39+
if (data == null
40+
|| data is string dataString
41+
&& string.IsNullOrEmpty(dataString))
42+
{
43+
continue;
44+
}
45+
46+
return data;
47+
}
3748
break;
3849
// Request body extraction is opt-in
3950
case RequestSize.None:
4051
_options.DiagnosticLogger.LogDebug("Skipping request body extraction.");
4152
break;
4253
default:
43-
_options.DiagnosticLogger.LogWarning("Unknown RequestSize {0}", _size);
54+
_options.DiagnosticLogger.LogWarning("Ignoring request with Size {0} and configuration RequestSize {1}",
55+
request.ContentLength, _size);
4456
break;
4557
}
4658

47-
if (extractRequestBody)
48-
{
49-
_options.DiagnosticLogger.LogDebug("Attempting to read request body of size: {0}, configured max: {1}.",
50-
request.ContentLength, _size);
51-
52-
foreach (var extractor in Extractors)
53-
{
54-
var data = extractor.ExtractPayload(request);
55-
56-
if (data == null
57-
|| data is string dataString
58-
&& string.IsNullOrEmpty(dataString))
59-
{
60-
continue;
61-
}
62-
63-
return data;
64-
}
65-
}
66-
6759
return null;
6860
}
6961
}

src/Sentry/Extensibility/RequestSize.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ public enum RequestSize
1919
/// </summary>
2020
Medium,
2121
/// <summary>
22-
/// A large payload is extracted.
22+
/// The SDK will always capture the request body. Sentry might truncate or reject the event if too large.
2323
/// </summary>
24-
Large
24+
Always
2525
}
2626
}

test/Sentry.AspNetCore.Tests/IntegrationMockedBackgroundWorker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ public void AllSettingsViaJson()
196196
#pragma warning disable 618
197197
Assert.True(options.IncludeRequestPayload);
198198
#pragma warning restore 618
199-
Assert.Equal(RequestSize.Large, options.MaxRequestBodySize);
199+
Assert.Equal(RequestSize.Always, options.MaxRequestBodySize);
200200
Assert.True(options.SendDefaultPii);
201201
Assert.True(options.IncludeActivityData);
202202
Assert.Equal(LogLevel.Error, options.MinimumBreadcrumbLevel);

test/Sentry.AspNetCore.Tests/ScopeExtensionsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class ScopeExtensionsTests
2121
#pragma warning disable 618
2222
IncludeRequestPayload = true,
2323
#pragma warning restore 618
24-
MaxRequestBodySize = RequestSize.Large
24+
MaxRequestBodySize = RequestSize.Always
2525
};
2626

2727
public ScopeExtensionsTests()
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using NSubstitute;
4+
using NSubstitute.ReturnsExtensions;
5+
using Sentry.Extensibility;
6+
using Xunit;
7+
8+
namespace Sentry.Tests.Extensibility
9+
{
10+
public class RequestBodyExtractionDispatcherTests
11+
{
12+
private class Fixture
13+
{
14+
public SentryOptions SentryOptions { get; set; } = new SentryOptions();
15+
public RequestSize RequestSize { get; set; } = RequestSize.Small;
16+
public IHttpRequest HttpRequest { get; set; } = Substitute.For<IHttpRequest>();
17+
public IRequestPayloadExtractor Extractor { get; set; } = Substitute.For<IRequestPayloadExtractor>();
18+
public IEnumerable<IRequestPayloadExtractor> Extractors { get; set; }
19+
20+
public Fixture()
21+
{
22+
HttpRequest.ContentLength.Returns(10);
23+
Extractor.ExtractPayload(Arg.Any<IHttpRequest>()).Returns("Result");
24+
Extractors = new[] { Extractor };
25+
}
26+
27+
public RequestBodyExtractionDispatcher GetSut() => new RequestBodyExtractionDispatcher(Extractors, SentryOptions, RequestSize);
28+
}
29+
30+
private readonly Fixture _fixture = new Fixture();
31+
32+
[Fact]
33+
public void ExtractPayload_DefaultFixture_ReadsMockPayload()
34+
{
35+
var sut = _fixture.GetSut();
36+
37+
var actual = sut.ExtractPayload(_fixture.HttpRequest);
38+
Assert.Same("Result", actual);
39+
}
40+
41+
[Fact]
42+
public void ExtractPayload_ExtractorEmptyString_ReturnsNull()
43+
{
44+
_fixture.Extractor.ExtractPayload(Arg.Any<IHttpRequest>()).Returns(string.Empty);
45+
var sut = _fixture.GetSut();
46+
47+
Assert.Null(sut.ExtractPayload(_fixture.HttpRequest));
48+
}
49+
50+
[Fact]
51+
public void ExtractPayload_ExtractorNull_ReturnsNull()
52+
{
53+
_fixture.Extractor.ExtractPayload(Arg.Any<IHttpRequest>()).ReturnsNull();
54+
var sut = _fixture.GetSut();
55+
56+
Assert.Null(sut.ExtractPayload(_fixture.HttpRequest));
57+
}
58+
59+
[Theory]
60+
[InlineData(RequestSize.None, 1, false)]
61+
[InlineData(RequestSize.Small, 999, true)]
62+
[InlineData(RequestSize.Small, 10_000, false)]
63+
[InlineData(RequestSize.Medium, 9999, true)]
64+
[InlineData(RequestSize.Medium, 100_000, false)]
65+
[InlineData(RequestSize.Always, int.MaxValue, true)] // 2 GB event? No problem...
66+
public void ExtractPayload_RequestSizeSmall_ContentLength(RequestSize requestSize, int contentLength, bool readBody)
67+
{
68+
_fixture.RequestSize = requestSize;
69+
_fixture.HttpRequest.ContentLength.Returns(contentLength);
70+
var sut = _fixture.GetSut();
71+
72+
Assert.Equal(readBody, sut.ExtractPayload(_fixture.HttpRequest) != null);
73+
}
74+
75+
[Fact]
76+
public void ExtractPayload_NullRequest_ReturnsNull()
77+
{
78+
var sut = _fixture.GetSut();
79+
Assert.Null(sut.ExtractPayload(null));
80+
}
81+
82+
[Fact]
83+
public void Ctor_NullExtractors_ThrowsArgumentNullException()
84+
{
85+
_fixture.Extractors = null;
86+
Assert.Throws<ArgumentNullException>(() => _fixture.GetSut());
87+
}
88+
89+
[Fact]
90+
public void Ctor_NullOptions_ThrowsArgumentNullException()
91+
{
92+
_fixture.SentryOptions = null;
93+
Assert.Throws<ArgumentNullException>(() => _fixture.GetSut());
94+
}
95+
}
96+
}

0 commit comments

Comments
 (0)