Skip to content

Commit 3d8bbe0

Browse files
committed
Added Better Errors for MultiPart requests (#6829)
1 parent b50b6c5 commit 3d8bbe0

File tree

6 files changed

+50
-14
lines changed

6 files changed

+50
-14
lines changed
Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using HotChocolate.AspNetCore.Properties;
1+
using static HotChocolate.AspNetCore.Properties.AspNetCoreResources;
22

33
namespace HotChocolate.AspNetCore;
44

@@ -9,32 +9,32 @@ internal static class ErrorHelper
99
{
1010
public static IError InvalidRequest()
1111
=> ErrorBuilder.New()
12-
.SetMessage(AspNetCoreResources.ErrorHelper_InvalidRequest)
12+
.SetMessage(ErrorHelper_InvalidRequest)
1313
.SetCode(ErrorCodes.Server.RequestInvalid)
1414
.Build();
1515

1616
public static IError RequestHasNoElements()
1717
=> ErrorBuilder.New()
18-
.SetMessage(AspNetCoreResources.ErrorHelper_RequestHasNoElements)
18+
.SetMessage(ErrorHelper_RequestHasNoElements)
1919
.SetCode(ErrorCodes.Server.RequestInvalid)
2020
.Build();
2121

2222
public static IError NoSupportedAcceptMediaType()
2323
=> ErrorBuilder.New()
24-
.SetMessage(AspNetCoreResources.ErrorHelper_NoSupportedAcceptMediaType)
24+
.SetMessage(ErrorHelper_NoSupportedAcceptMediaType)
2525
.SetCode(ErrorCodes.Server.NoSupportedAcceptMediaType)
2626
.Build();
2727

2828
public static IQueryResult TypeNameIsEmpty()
2929
=> QueryResultBuilder.CreateError(
3030
new Error(
31-
AspNetCoreResources.ErrorHelper_TypeNameIsEmpty,
31+
ErrorHelper_TypeNameIsEmpty,
3232
code: ErrorCodes.Server.TypeParameterIsEmpty));
3333

3434
public static IQueryResult InvalidTypeName(string typeName)
3535
=> QueryResultBuilder.CreateError(
3636
new Error(
37-
AspNetCoreResources.ErrorHelper_InvalidTypeName,
37+
ErrorHelper_InvalidTypeName,
3838
code: ErrorCodes.Server.InvalidTypeName,
3939
extensions: new Dictionary<string, object?>
4040
{
@@ -44,7 +44,7 @@ public static IQueryResult InvalidTypeName(string typeName)
4444
public static IQueryResult TypeNotFound(string typeName)
4545
=> QueryResultBuilder.CreateError(
4646
new Error(
47-
string.Format(AspNetCoreResources.ErrorHelper_TypeNotFound, typeName),
47+
string.Format(ErrorHelper_TypeNotFound, typeName),
4848
code: ErrorCodes.Server.TypeDoesNotExist,
4949
extensions: new Dictionary<string, object?>
5050
{
@@ -54,10 +54,16 @@ public static IQueryResult TypeNotFound(string typeName)
5454
public static IQueryResult InvalidAcceptMediaType(string headerValue)
5555
=> QueryResultBuilder.CreateError(
5656
new Error(
57-
string.Format(AspNetCoreResources.ErrorHelper_InvalidAcceptMediaType, headerValue),
57+
string.Format(ErrorHelper_InvalidAcceptMediaType, headerValue),
5858
code: ErrorCodes.Server.InvalidAcceptHeaderValue,
5959
extensions: new Dictionary<string, object?>
6060
{
6161
{ nameof(headerValue), headerValue }
6262
}));
63+
64+
public static IQueryResult MultiPartRequestPreflightRequired()
65+
=> QueryResultBuilder.CreateError(
66+
new Error(
67+
ErrorHelper_MultiPartRequestPreflightRequired,
68+
code: ErrorCodes.Server.MultiPartPreflightRequired));
6369
}

src/HotChocolate/AspNetCore/src/AspNetCore/HttpMultipartMiddleware.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using HotChocolate.AspNetCore.Serialization;
77
using HotChocolate.Language;
88
using HotChocolate.Utilities;
9+
using static System.Net.HttpStatusCode;
10+
using static HotChocolate.AspNetCore.ErrorHelper;
911
using static HotChocolate.AspNetCore.Properties.AspNetCoreResources;
1012
using HttpRequestDelegate = Microsoft.AspNetCore.Http.RequestDelegate;
1113

@@ -16,6 +18,7 @@ public sealed class HttpMultipartMiddleware : HttpPostMiddlewareBase
1618
private const string _operations = "operations";
1719
private const string _map = "map";
1820
private readonly FormOptions _formOptions;
21+
private readonly IQueryResult _multipartRequestError = MultiPartRequestPreflightRequired();
1922

2023
public HttpMultipartMiddleware(
2124
HttpRequestDelegate next,
@@ -40,10 +43,16 @@ public override async Task InvokeAsync(HttpContext context)
4043
{
4144
if (HttpMethods.IsPost(context.Request.Method) &&
4245
GetOptions(context).EnableMultipartRequests &&
43-
ParseContentType(context) == RequestContentType.Form &&
44-
(context.Request.Headers.ContainsKey(HttpHeaderKeys.Preflight) ||
45-
!GetOptions(context).EnforceMultipartRequestsPreflightHeader))
46+
ParseContentType(context) == RequestContentType.Form)
4647
{
48+
if (!context.Request.Headers.ContainsKey(HttpHeaderKeys.Preflight) &&
49+
GetOptions(context).EnforceMultipartRequestsPreflightHeader)
50+
{
51+
var headerResult = HeaderUtilities.GetAcceptHeader(context.Request);
52+
await WriteResultAsync(context, _multipartRequestError, headerResult.AcceptMediaTypes, BadRequest);
53+
return;
54+
}
55+
4756
if (!IsDefaultSchema)
4857
{
4958
context.Items[WellKnownContextData.SchemaName] = SchemaName;

src/HotChocolate/AspNetCore/src/AspNetCore/Properties/AspNetCoreResources.Designer.cs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/HotChocolate/AspNetCore/src/AspNetCore/Properties/AspNetCoreResources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,7 @@
138138
<data name="ErrorHelper_TypeNameIsEmpty" xml:space="preserve">
139139
<value>The specified types argument is empty.</value>
140140
</data>
141+
<data name="ErrorHelper_MultiPartRequestPreflightRequired" xml:space="preserve">
142+
<value>Multi-part requests must include a GraphQL preflight header.</value>
143+
</data>
141144
</root>
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
{
2-
"ContentType": null,
3-
"StatusCode": "NotFound",
2+
"ContentType": "application/graphql-response+json; charset=utf-8",
3+
"StatusCode": "BadRequest",
44
"Data": null,
5-
"Errors": null,
5+
"Errors": [
6+
{
7+
"message": "Multi-part requests must include a GraphQL preflight header.",
8+
"extensions": {
9+
"code": "HC0077"
10+
}
11+
}
12+
],
613
"Extensions": null
714
}

src/HotChocolate/Core/src/Abstractions/ErrorCodes.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ public static class Server
192192
/// The request did not specify any supported accept media type.
193193
/// </summary>
194194
public const string InvalidAcceptHeaderValue = "HC0064";
195+
196+
/// <summary>
197+
/// Multi-part requests must include a GraphQL preflight header.
198+
/// </summary>
199+
public const string MultiPartPreflightRequired = "HC0077";
195200
}
196201

197202
public static class Schema

0 commit comments

Comments
 (0)