Skip to content

Commit 073b2f7

Browse files
committed
Set property to enable streaming in WASM and gRPC-Web
1 parent c6b8f6c commit 073b2f7

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

src/Grpc.Net.Client.Web/GrpcWebHandler.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ namespace Grpc.Net.Client.Web
3737
/// </remarks>
3838
public sealed class GrpcWebHandler : DelegatingHandler
3939
{
40+
internal const string WebAssemblyEnableStreamingResponseKey = "WebAssemblyEnableStreamingResponse";
41+
4042
/// <summary>
4143
/// Gets or sets the HTTP version to use when making gRPC-Web calls.
4244
/// <para>
@@ -114,6 +116,16 @@ protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage reques
114116
private async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
115117
{
116118
request.Content = new GrpcWebRequestContent(request.Content, GrpcWebMode);
119+
120+
// Set WebAssemblyEnableStreamingResponse to true on gRPC-Web request.
121+
// https://github.com/mono/mono/blob/a0d69a4e876834412ba676f544d447ec331e7c01/sdks/wasm/framework/src/System.Net.Http.WebAssemblyHttpHandler/WebAssemblyHttpHandler.cs#L149
122+
//
123+
// This must be set so WASM will stream the response. Without this setting the WASM HTTP handler will only
124+
// return content once the entire response has been downloaded. This breaks server streaming.
125+
//
126+
// https://github.com/mono/mono/issues/18718
127+
request.Properties[WebAssemblyEnableStreamingResponseKey] = true;
128+
117129
if (HttpVersion != null)
118130
{
119131
// This doesn't guarantee that the specified version is used. Some handlers will ignore it.

test/Grpc.Net.Client.Tests/Web/GrpcWebHandlerTests.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,64 @@ public async Task HttpVersion_Set_HttpRequestMessageVersionChanged()
8787
Assert.AreEqual(HttpVersion.Version20, response.Version);
8888
}
8989

90+
[Test]
91+
public async Task SendAsync_GrpcCall_ResponseStreamingPropertySet()
92+
{
93+
// Arrange
94+
var request = new HttpRequestMessage
95+
{
96+
Version = HttpVersion.Version20,
97+
Content = new ByteArrayContent(Array.Empty<byte>())
98+
{
99+
Headers = { ContentType = new MediaTypeHeaderValue("application/grpc") }
100+
}
101+
};
102+
var testHttpHandler = new TestHttpHandler();
103+
var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, testHttpHandler);
104+
var messageInvoker = new HttpMessageInvoker(grpcWebHandler);
105+
106+
// Act
107+
await messageInvoker.SendAsync(request, CancellationToken.None);
108+
109+
// Assert
110+
Assert.AreEqual(true, testHttpHandler.WebAssemblyEnableStreamingResponse);
111+
}
112+
113+
[Test]
114+
public async Task SendAsync_NonGrpcCall_ResponseStreamingPropertyNotSet()
115+
{
116+
// Arrange
117+
var request = new HttpRequestMessage
118+
{
119+
Version = HttpVersion.Version20,
120+
Content = new ByteArrayContent(Array.Empty<byte>())
121+
{
122+
Headers = { ContentType = new MediaTypeHeaderValue("application/text") }
123+
}
124+
};
125+
var testHttpHandler = new TestHttpHandler();
126+
var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, testHttpHandler);
127+
var messageInvoker = new HttpMessageInvoker(grpcWebHandler);
128+
129+
// Act
130+
await messageInvoker.SendAsync(request, CancellationToken.None);
131+
132+
// Assert
133+
Assert.AreEqual(null, testHttpHandler.WebAssemblyEnableStreamingResponse);
134+
}
135+
90136
private class TestHttpHandler : HttpMessageHandler
91137
{
92138
public Version? RequestVersion { get; private set; }
139+
public bool? WebAssemblyEnableStreamingResponse { get; private set; }
93140

94141
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
95142
{
96143
RequestVersion = request.Version;
144+
if (request.Properties.TryGetValue(GrpcWebHandler.WebAssemblyEnableStreamingResponseKey, out var enableStreaming))
145+
{
146+
WebAssemblyEnableStreamingResponse = (bool)enableStreaming;
147+
}
97148

98149
return Task.FromResult(new HttpResponseMessage()
99150
{

0 commit comments

Comments
 (0)