Skip to content

Commit 5e46729

Browse files
authored
Merge pull request #174 from getsentry/feature/max-request-body-size
feat: MaxRequest for ASP.NET and Core
2 parents 6b3c204 + 950b7eb commit 5e46729

29 files changed

+676
-62
lines changed

Directory.Build.props

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@
2323
<FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net461'">$(BaseFrameworkPathOverrideForMono)/4.6.1-api</FrameworkPathOverride>
2424
<EnableFrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != ''">true</EnableFrameworkPathOverride>
2525
</PropertyGroup>
26+
27+
<PropertyGroup Condition="$(TargetFramework.StartsWith('net4'))">
28+
<DefineConstants>SYSTEM_WEB;$(AdditionalConstants)</DefineConstants>
29+
</PropertyGroup>
2630
</Project>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Collections.Generic;
2+
using System.IO;
3+
using System.Linq;
4+
using Microsoft.AspNetCore.Http;
5+
using Sentry.Extensibility;
6+
7+
namespace Sentry.AspNetCore
8+
{
9+
internal class HttpRequestAdapter : IHttpRequest
10+
{
11+
private readonly HttpRequest _request;
12+
13+
public HttpRequestAdapter(HttpRequest request) => _request = request;
14+
15+
public long? ContentLength => _request?.ContentLength;
16+
public string ContentType => _request?.ContentType;
17+
public Stream Body => _request?.Body;
18+
19+
public IEnumerable<KeyValuePair<string, IEnumerable<string>>> Form =>
20+
_request?.Form.Select(k => new KeyValuePair<string, IEnumerable<string>>(k.Key, k.Value))
21+
?? Enumerable.Empty<KeyValuePair<string, IEnumerable<string>>>();
22+
}
23+
}

src/Sentry.AspNetCore/IRequestPayloadExtractor.cs

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/Sentry.AspNetCore/ScopeExtensions.cs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using Microsoft.AspNetCore.Http;
66
using Microsoft.Extensions.DependencyInjection;
77
using Microsoft.Net.Http.Headers;
8+
using Sentry.Extensibility;
9+
using Sentry.Protocol;
810

911
namespace Sentry.AspNetCore
1012
{
@@ -90,31 +92,24 @@ private static void SetEnv(Scope scope, HttpContext context, SentryAspNetCoreOpt
9092
}
9193
}
9294

93-
private static void SetBody(Scope scope, HttpContext context, SentryAspNetCoreOptions options)
95+
private static void SetBody(BaseScope scope, HttpContext context, SentryAspNetCoreOptions options)
9496
{
95-
if (options?.IncludeRequestPayload == true)
97+
if (context == null || scope == null || options == null)
9698
{
97-
// GetServices<IRequestPayloadExtractor> throws! Shouldn't it return Enumerable.Empty<T>?
98-
var extractors = context.RequestServices.GetService<IEnumerable<IRequestPayloadExtractor>>();
99-
if (extractors == null)
100-
{
101-
return;
102-
}
103-
104-
foreach (var extractor in extractors)
105-
{
106-
var data = extractor.ExtractPayload(context.Request);
99+
return;
100+
}
107101

108-
if (data == null
109-
|| data is string dataString
110-
&& string.IsNullOrEmpty(dataString))
111-
{
112-
continue;
113-
}
102+
var extractors = context.RequestServices.GetService<IEnumerable<IRequestPayloadExtractor>>();
103+
if (extractors == null)
104+
{
105+
return;
106+
}
107+
var dispatcher = new RequestBodyExtractionDispatcher(extractors, options, () => options.MaxRequestBodySize);
114108

115-
scope.Request.Data = data;
116-
break;
117-
}
109+
var body = dispatcher.ExtractPayload(new HttpRequestAdapter(context.Request));
110+
if (body != null)
111+
{
112+
scope.Request.Data = body;
118113
}
119114
}
120115

src/Sentry.AspNetCore/SentryAspNetCoreOptions.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System;
2+
using Sentry.Extensibility;
13
using Sentry.Extensions.Logging;
24

35
namespace Sentry.AspNetCore
@@ -14,7 +16,13 @@ public class SentryAspNetCoreOptions : SentryLoggingOptions
1416
/// <value>
1517
/// <c>true</c> if [the request payload shall be included in events]; otherwise, <c>false</c>.
1618
/// </value>
17-
public bool IncludeRequestPayload { get; set; }
19+
[Obsolete("Use MaxRequestBodySize instead.")]
20+
public bool IncludeRequestPayload
21+
{
22+
get => MaxRequestBodySize != RequestSize.None;
23+
// As originally there was no truncation, setting to Large.
24+
set => MaxRequestBodySize = value ? RequestSize.Always : RequestSize.None;
25+
}
1826

1927
/// <summary>
2028
/// Gets or sets a value indicating whether [include System.Diagnostic.Activity data] to events.
@@ -25,5 +33,14 @@ public class SentryAspNetCoreOptions : SentryLoggingOptions
2533
/// <see cref="System.Diagnostics.Activity"/>
2634
/// <seealso href="https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/ActivityUserGuide.md"/>
2735
public bool IncludeActivityData { get; set; }
36+
37+
/// <summary>
38+
/// Controls the size of the request body to extract if any.
39+
/// </summary>
40+
/// <remarks>
41+
/// No truncation is done by the SDK.
42+
/// If the request body is larger than the accepted size, nothing is sent.
43+
/// </remarks>
44+
public RequestSize MaxRequestBodySize { get; set; }
2845
}
2946
}

src/Sentry.AspNetCore/SentryMiddleware.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Microsoft.AspNetCore.Http.Internal;
99
using Microsoft.Extensions.Logging;
1010
using Microsoft.Extensions.Options;
11+
using Sentry.Extensibility;
1112
using Sentry.Reflection;
1213

1314
namespace Sentry.AspNetCore
@@ -79,7 +80,7 @@ public async Task InvokeAsync(HttpContext context)
7980

8081
using (hub.PushAndLockScope())
8182
{
82-
if (_options?.IncludeRequestPayload == true)
83+
if (_options != null && _options.MaxRequestBodySize != RequestSize.None)
8384
{
8485
context.Request.EnableRewind();
8586
}

src/Sentry.AspNetCore/BaseRequestPayloadExtractor.cs renamed to src/Sentry/Extensibility/BaseRequestPayloadExtractor.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
using Microsoft.AspNetCore.Http;
2-
3-
namespace Sentry.AspNetCore
1+
namespace Sentry.Extensibility
42
{
53
public abstract class BaseRequestPayloadExtractor : IRequestPayloadExtractor
64
{
7-
public object ExtractPayload(HttpRequest request)
5+
public object ExtractPayload(IHttpRequest request)
86
{
97
if (!request.Body.CanSeek
108
|| !request.Body.CanRead
@@ -26,8 +24,8 @@ public object ExtractPayload(HttpRequest request)
2624
}
2725
}
2826

29-
protected abstract bool IsSupported(HttpRequest request);
27+
protected abstract bool IsSupported(IHttpRequest request);
3028

31-
protected abstract object DoExtractPayLoad(HttpRequest request);
29+
protected abstract object DoExtractPayLoad(IHttpRequest request);
3230
}
3331
}

src/Sentry.AspNetCore/DefaultRequestPayloadExtractor.cs renamed to src/Sentry/Extensibility/DefaultRequestPayloadExtractor.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
using System.IO;
22
using System.Text;
3-
using Microsoft.AspNetCore.Http;
43

5-
namespace Sentry.AspNetCore
4+
namespace Sentry.Extensibility
65
{
76
public class DefaultRequestPayloadExtractor : BaseRequestPayloadExtractor
87
{
9-
protected override bool IsSupported(HttpRequest request) => true;
8+
protected override bool IsSupported(IHttpRequest request) => true;
109

11-
protected override object DoExtractPayLoad(HttpRequest request)
10+
protected override object DoExtractPayLoad(IHttpRequest request)
1211
{
1312
// https://github.com/dotnet/corefx/blob/master/src/Common/src/CoreLib/System/IO/StreamReader.cs#L186
1413
// Default parameters other than 'leaveOpen'

src/Sentry/Extensibility/DiagnosticLoggerExtensions.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public static void LogDebug<TArg, TArg2>(
1717
string message,
1818
TArg arg,
1919
TArg2 arg2)
20-
=> logger.LogIfEnabled(SentryLevel.Debug, message, arg, arg2);
20+
=> logger.LogIfEnabled(SentryLevel.Debug, message, arg, arg2);
2121

2222
public static void LogDebug(
2323
this IDiagnosticLogger logger,
@@ -40,7 +40,7 @@ public static void LogInfo<TArg, TArg2>(
4040
string message,
4141
TArg arg,
4242
TArg2 arg2)
43-
=> logger.LogIfEnabled(SentryLevel.Info, message, arg, arg2);
43+
=> logger.LogIfEnabled(SentryLevel.Info, message, arg, arg2);
4444

4545
public static void LogWarning(
4646
this IDiagnosticLogger logger,
@@ -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,
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
using System;
22
using System.Linq;
3-
using Microsoft.AspNetCore.Http;
43

5-
namespace Sentry.AspNetCore
4+
namespace Sentry.Extensibility
65
{
76
public class FormRequestPayloadExtractor : BaseRequestPayloadExtractor
87
{
98
private const string SupportedContentType = "application/x-www-form-urlencoded";
109

11-
protected override bool IsSupported(HttpRequest request)
10+
protected override bool IsSupported(IHttpRequest request)
1211
=> SupportedContentType
1312
.Equals(request.ContentType, StringComparison.InvariantCulture);
1413

15-
protected override object DoExtractPayLoad(HttpRequest request)
14+
protected override object DoExtractPayLoad(IHttpRequest request)
1615
=> request.Form?.ToDictionary(k => k.Key, v => v.Value);
1716
}
1817
}

0 commit comments

Comments
 (0)