Skip to content

Commit 0f6bb6e

Browse files
committed
feat: Handle invalid Base64 body
1 parent d910ce5 commit 0f6bb6e

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

src/Voxel.MiddyNet.HttpJsonBodyParserMiddleware/HttpJsonBodyParserMiddleware.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Text;
23
using Amazon.Lambda.APIGatewayEvents;
34
using Newtonsoft.Json;
45
using System.Threading.Tasks;
@@ -9,27 +10,32 @@ public class HttpJsonBodyParserMiddleware<T> : ILambdaMiddleware<APIGatewayProxy
910
{
1011
public Task Before(APIGatewayProxyRequest lambdaEvent, MiddyNetContext context)
1112
{
12-
if (!HasJSONContentHeaders(lambdaEvent))
13+
if (!HasJsonContentHeaders(lambdaEvent))
1314
{
1415
context.AdditionalContext.Add("Body", lambdaEvent.Body);
1516
return Task.CompletedTask;
1617
}
1718

19+
if (lambdaEvent.IsBase64Encoded)
20+
{
21+
lambdaEvent.Body = Encoding.UTF8.GetString(Convert.FromBase64String(lambdaEvent.Body));
22+
}
23+
1824
T source;
1925
try
2026
{
2127
source = JsonConvert.DeserializeObject<T>(lambdaEvent.Body);
2228
}
2329
catch (JsonReaderException)
2430
{
25-
throw new Exception($"Error parsing \"{lambdaEvent.Body}\" to type {typeof(T)}");
31+
throw new Exception("Content type defined as JSON but an invalid JSON was provided");
2632
}
2733

2834
context.AdditionalContext.Add("Body", source);
2935
return Task.CompletedTask;
3036
}
3137

32-
private static bool HasJSONContentHeaders(APIGatewayProxyRequest lambdaEvent)
38+
private static bool HasJsonContentHeaders(APIGatewayProxyRequest lambdaEvent)
3339
{
3440
return lambdaEvent.Headers != null &&
3541
(lambdaEvent.Headers.ContainsKey("Content-Type") &&

test/Voxel.MiddyNet.HttpJsonBodyParserMiddleware.Tests/HttpJsonBodyParserMiddlewareShould.cs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Text;
34
using System.Threading.Tasks;
45
using Amazon.Lambda.APIGatewayEvents;
56
using Amazon.Lambda.Core;
@@ -41,7 +42,7 @@ public async Task ProcessTheJsonRequest()
4142
[Fact]
4243
public async Task ErrorWhenJsonNotMapsToObject()
4344
{
44-
var source = "Not Mapped object" + serializedExpectation;
45+
var source = "Make it broken" + serializedExpectation;
4546
var request = new APIGatewayProxyRequest()
4647
{
4748
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
@@ -50,7 +51,7 @@ public async Task ErrorWhenJsonNotMapsToObject()
5051
var middleware = new HttpJsonBodyParserMiddleware<TestObject>();
5152
Action action = () => middleware.Before(request, context);
5253

53-
action.Should().Throw<Exception>().WithMessage($"Error parsing \"{source}\" to type {typeof(TestObject)}");
54+
action.Should().Throw<Exception>().WithMessage("Content type defined as JSON but an invalid JSON was provided");
5455
}
5556

5657
[Fact]
@@ -66,5 +67,43 @@ public async Task NotProcessTheBodyIfNoHeaderIsPassed()
6667
context.AdditionalContext.ContainsKey("Body").Should().BeTrue();
6768
context.AdditionalContext["Body"].Should().Be(serializedExpectation);
6869
}
70+
71+
[Fact]
72+
public async Task HandleABase64Body()
73+
{
74+
string base64Serialized = Convert.ToBase64String(Encoding.UTF8.GetBytes(serializedExpectation));
75+
76+
var request = new APIGatewayProxyRequest()
77+
{
78+
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
79+
IsBase64Encoded = true,
80+
Body = base64Serialized
81+
};
82+
83+
var middleware = new HttpJsonBodyParserMiddleware<TestObject>();
84+
await middleware.Before(request, context);
85+
86+
context.AdditionalContext.ContainsKey("Body").Should().BeTrue();
87+
context.AdditionalContext["Body"].Should().BeEquivalentTo(expectation);
88+
}
89+
90+
[Fact]
91+
public async Task HandleInvalidBase64Body()
92+
{
93+
var source = "Make it broken" + serializedExpectation;
94+
string base64Serialized = Convert.ToBase64String(Encoding.UTF8.GetBytes(source));
95+
96+
var request = new APIGatewayProxyRequest()
97+
{
98+
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
99+
IsBase64Encoded = true,
100+
Body = base64Serialized
101+
};
102+
103+
var middleware = new HttpJsonBodyParserMiddleware<TestObject>();
104+
Action action = () => middleware.Before(request, context);
105+
106+
action.Should().Throw<Exception>().WithMessage("Content type defined as JSON but an invalid JSON was provided");
107+
}
69108
}
70109
}

0 commit comments

Comments
 (0)