Skip to content

Commit 59062ec

Browse files
authored
Extra metadata filtering in client and server (#1052)
1 parent 7fe4595 commit 59062ec

File tree

6 files changed

+36
-5
lines changed

6 files changed

+36
-5
lines changed

src/Grpc.AspNetCore.Server/Internal/GrpcProtocolConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ internal static class GrpcProtocolConstants
7777
MessageEncodingHeader,
7878
MessageAcceptEncodingHeader,
7979
TimeoutHeader,
80+
HeaderNames.ContentEncoding,
8081
HeaderNames.ContentType,
8182
HeaderNames.TE,
8283
HeaderNames.Host,

src/Grpc.AspNetCore.Server/Internal/GrpcProtocolHelpers.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,5 +231,10 @@ internal static bool CanWriteCompressed(WriteOptions? writeOptions)
231231

232232
return canCompress;
233233
}
234+
235+
internal static bool ShouldSkipHeader(string name)
236+
{
237+
return name.StartsWith(':') || GrpcProtocolConstants.FilteredHeaders.Contains(name);
238+
}
234239
}
235240
}

src/Grpc.AspNetCore.Server/Internal/HttpContextServerCallContext.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,12 @@ protected override Metadata RequestHeadersCore
117117

118118
foreach (var header in HttpContext.Request.Headers)
119119
{
120-
// gRPC metadata contains a subset of the request headers
121-
// Filter out pseudo headers (start with :) and other known headers
122-
if (header.Key.StartsWith(':') || GrpcProtocolConstants.FilteredHeaders.Contains(header.Key))
120+
if (GrpcProtocolHelpers.ShouldSkipHeader(header.Key))
123121
{
124122
continue;
125123
}
126-
else if (header.Key.EndsWith(Metadata.BinaryHeaderSuffix, StringComparison.OrdinalIgnoreCase))
124+
125+
if (header.Key.EndsWith(Metadata.BinaryHeaderSuffix, StringComparison.OrdinalIgnoreCase))
127126
{
128127
_requestHeaders.Add(header.Key, GrpcProtocolHelpers.ParseBinaryHeader(header.Value));
129128
}

src/Grpc.Net.Client/Internal/GrpcProtocolHelpers.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ internal static bool ShouldSkipHeader(string name)
104104
|| string.Equals(name, GrpcProtocolConstants.MessageTrailer, StringComparison.OrdinalIgnoreCase)
105105
|| string.Equals(name, GrpcProtocolConstants.MessageEncodingHeader, StringComparison.OrdinalIgnoreCase)
106106
|| string.Equals(name, GrpcProtocolConstants.MessageAcceptEncodingHeader, StringComparison.OrdinalIgnoreCase);
107+
case 'c':
108+
case 'C':
109+
// Exclude known HTTP headers. This matches Grpc.Core client behavior.
110+
return string.Equals(name, "content-encoding", StringComparison.OrdinalIgnoreCase)
111+
|| string.Equals(name, "content-type", StringComparison.OrdinalIgnoreCase);
107112
default:
108113
return false;
109114
}

test/Grpc.AspNetCore.Server.Tests/HttpContextServerCallContextTests.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
using System.Linq;
2525
using System.Net;
2626
using System.Security.Cryptography.X509Certificates;
27+
using System.Text;
2728
using System.Threading;
2829
using System.Threading.Tasks;
2930
using Grpc.AspNetCore.Server.Internal;
@@ -546,18 +547,34 @@ public void UserState_AddState_AddedToHttpContextItems()
546547
}
547548

548549
[TestCase("grpc-accept-encoding", false)]
550+
[TestCase("GRPC-ACCEPT-ENCODING", false)]
549551
[TestCase("grpc-encoding", false)]
552+
[TestCase("GRPC-ENCODING", false)]
550553
[TestCase("grpc-timeout", false)]
554+
[TestCase("GRPC-TIMEOUT", false)]
551555
[TestCase("content-type", false)]
556+
[TestCase("CONTENT-TYPE", false)]
557+
[TestCase("content-encoding", false)]
558+
[TestCase("CONTENT-ENCODING", false)]
552559
[TestCase("te", false)]
560+
[TestCase("TE", false)]
553561
[TestCase("host", false)]
562+
[TestCase("HOST", false)]
554563
[TestCase("accept-encoding", false)]
564+
[TestCase("ACCEPT-ENCODING", false)]
555565
[TestCase("user-agent", true)]
566+
[TestCase("USER-AGENT", true)]
567+
[TestCase("grpc-status-details-bin", true)]
568+
[TestCase("GRPC-STATUS-DETAILS-BIN", true)]
556569
public void RequestHeaders_ManyHttpRequestHeaders_HeadersFiltered(string headerName, bool addedToRequestHeaders)
557570
{
558571
// Arrange
559572
var httpContext = new DefaultHttpContext();
560-
httpContext.Request.Headers[headerName] = "value";
573+
574+
// A base64 valid value is required for -bin headers
575+
var value = Convert.ToBase64String(Encoding.UTF8.GetBytes("Hello world"));
576+
httpContext.Request.Headers[headerName] = value;
577+
561578
var serverCallContext = CreateServerCallContext(httpContext);
562579

563580
// Act

test/Grpc.Net.Client.Tests/GrpcProtocolHelpersTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ public void EncodeTimeout(int milliseconds, string expected)
6666
[TestCase("custom", false)]
6767
[TestCase("grpc-status-details-bin", false)]
6868
[TestCase("GRPC-STATUS-DETAILS-BIN", false)]
69+
[TestCase("content-encoding", true)]
70+
[TestCase("CONTENT-ENCODING", true)]
71+
[TestCase("content-type", true)]
72+
[TestCase("CONTENT-TYPE", true)]
6973
public void ShouldSkipHeader(string header, bool skipped)
7074
{
7175
var result = GrpcProtocolHelpers.ShouldSkipHeader(header);

0 commit comments

Comments
 (0)