10BC0 Merge pull request #461 from samyonr/support_chunked_by_PostAsJsonAsync · EntityGraphQL/EntityGraphQL@fe9fb37 · GitHub
[go: up one dir, main page]

Skip to content

Commit fe9fb37

Browse files
authored
Merge pull request #461 from samyonr/support_chunked_by_PostAsJsonAsync
fix `EntityGraphQLEndpointRouteExtensions.MapGraphQL` to support chunked requests sent via PostAsJsonAsync
2 parents a91faf5 + 0d0ad5f commit fe9fb37

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

src/EntityGraphQL.AspNet/Extensions/EntityGraphQLEndpointRouteExtensions.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@ public static IEndpointRouteBuilder MapGraphQL<TQueryType>(
6262
context.Response.StatusCode = StatusCodes.Status415UnsupportedMediaType;
6363
return;
6464
}
65-
if (context.Request.ContentLength == null || context.Request.ContentLength == 0)
65+
var isChunked = context.Request.Headers.TransferEncoding
66+
.Any(h => h is not null && h.Equals("chunked", StringComparison.OrdinalIgnoreCase));
67+
68+
if (!isChunked && (context.Request.ContentLength == null ||
69+
context.Request.ContentLength == 0))
6670
{
6771
context.Response.StatusCode = StatusCodes.Status400BadRequest;
6872
return;

src/tests/EntityGraphQL.AspNet.Tests/EntityGraphQLEndpointRouteExtensionsTests.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Net;
22
using System.Net.Http.Headers;
3+
using System.Net.Http.Json;
34
using System.Net.Sockets;
45
using System.Text;
56
using System.Text.Json.Nodes;
@@ -528,4 +529,34 @@ public async Task GraphQL_Endpoint_FollowSpec_Supports_Header_Not_First()
528529
"Response text did not contain an expected Content-Type header. Received: " + responseText
529530
);
530531
}
531-
}
532+
533+
[Fact]
534+
public async Task GraphQL_Endpoint_200_On_Chunked_Data_Query()
535+
{
536+
// The second, real Kestrel-based WebApplication
537+
WebApplication realApp = _factory.RealApp ?? throw new InvalidOperationException("RealApp is null.");
538+
539+
// Get the real ephemeral port
540+
IServer server = realApp.Services.GetRequiredService<IServer>();
541+
IServerAddressesFeature addresses = server.Features.Get<IServerAddressesFeature>()!;
542+
string address = addresses.Addresses.First(); // e.g. http://127.0.0.1:12345
543+
Uri uri = new(address);
544+
545+
HttpClient client = new();
546+
client.BaseAddress = new Uri($"http://{uri.Host}:{uri.Port}");
547+
client.DefaultRequestHeaders.Add("Accept", "*/*");
548+
// PostAsJsonAsync adds the following header:
549+
// Transfer-Encoding = chunked
550+
// but ContentLength isn't forwarded, hence it's null or zero
551+
// if PostAsJsonAsync is used with WebApplicationFactory,
552+
// i.e. the in-memory test server, with no network involved,
553+
// it works fine and the ContentLength is set correctly.
554+
// hence, the CustomWebApplicationFactory is used to ensure
555+
// network communication is used, and the ContentLength is not set.
556+
HttpResponseMessage resp = await client.PostAsJsonAsync("/graphql", new { query = "{ hello }" });
557+
resp.EnsureSuccessStatusCode();
558+
559+
string json = await resp.Content.ReadAsStringAsync();
560+
Assert.Contains("\"hello\":\"world\"", json);
561+
}
562+
}

0 commit comments

Comments
 (0)
0