Skip to content

Trim some HttpHeader parsing logic on browser-wasm #52572

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
<type fullname="System.Net.Http.HttpClient">
<method signature="System.Boolean IsNativeHandlerEnabled()" body="stub" value="true" feature="System.Net.Http.UseNativeHttpHandler" featurevalue="true" />
</type>
<type fullname="System.Net.Http.Headers.KnownHeaders">
<method signature="System.Boolean get_MinimalHeaderValidation()" body="stub" value="true" feature="System.Net.Http.MinimalHeaderValidation" featurevalue="true" />
</type>
</assembly>
</linker>
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ internal sealed class GenericHeaderParser : BaseHeaderParser
internal static readonly GenericHeaderParser MultipleValueNameValueWithParametersParser = new GenericHeaderParser(true, NameValueWithParametersHeaderValue.GetNameValueWithParametersLength);
internal static readonly GenericHeaderParser SingleValueNameValueParser = new GenericHeaderParser(false, ParseNameValue);
internal static readonly GenericHeaderParser MultipleValueNameValueParser = new GenericHeaderParser(true, ParseNameValue);
internal static readonly GenericHeaderParser MailAddressParser = new GenericHeaderParser(false, ParseMailAddress);
internal static readonly GenericHeaderParser SingleValueProductParser = new GenericHeaderParser(false, ParseProduct);
internal static readonly GenericHeaderParser MultipleValueProductParser = new GenericHeaderParser(true, ParseProduct);
internal static readonly GenericHeaderParser RangeConditionParser = new GenericHeaderParser(false, RangeConditionHeaderValue.GetRangeConditionLength);
Expand All @@ -37,6 +36,9 @@ internal sealed class GenericHeaderParser : BaseHeaderParser
internal static readonly GenericHeaderParser SingleValueWarningParser = new GenericHeaderParser(false, WarningHeaderValue.GetWarningLength);
internal static readonly GenericHeaderParser MultipleValueWarningParser = new GenericHeaderParser(true, WarningHeaderValue.GetWarningLength);

// These parsers are not cached in a static field, so they can be trimmed when not needed
internal static GenericHeaderParser GetMailAddressParser() => new GenericHeaderParser(false, ParseMailAddress);

#endregion

private readonly GetParsedValueLengthDelegate _getParsedValueLength;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ namespace System.Net.Http.Headers
{
internal static class KnownHeaders
{
private static bool MinimalHeaderValidation { get; } =
AppContext.TryGetSwitch("System.Net.Http.MinimalHeaderValidation", out bool minimalHeaderValidation) ? minimalHeaderValidation : false;

// If you add a new entry here, you need to add it to TryGetKnownHeader below as well.

public static readonly KnownHeader PseudoStatus = new KnownHeader(":status", HttpHeaderType.Response, parser: null);
Expand All @@ -26,7 +29,7 @@ internal static class KnownHeaders
public static readonly KnownHeader AccessControlMaxAge = new KnownHeader("Access-Control-Max-Age");
public static readonly KnownHeader Age = new KnownHeader("Age", HttpHeaderType.Response | HttpHeaderType.NonTrailing, TimeSpanHeaderParser.Parser, null, H2StaticTable.Age, H3StaticTable.Age0);
public static readonly KnownHeader Allow = new KnownHeader("Allow", HttpHeaderType.Content, GenericHeaderParser.TokenListParser, null, H2StaticTable.Allow);
public static readonly KnownHeader AltSvc = new KnownHeader("Alt-Svc", HttpHeaderType.Response, AltSvcHeaderParser.Parser, http3StaticTableIndex: H3StaticTable.AltSvcClear);
public static readonly KnownHeader AltSvc = new KnownHeader("Alt-Svc", HttpHeaderType.Response, MinimalHeaderValidation ? null : AltSvcHeaderParser.Parser, http3StaticTableIndex: H3StaticTable.AltSvcClear);
public static readonly KnownHeader AltUsed = new KnownHeader("Alt-Used", HttpHeaderType.Request, parser: null);
public static readonly KnownHeader Authorization = new KnownHeader("Authorization", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.SingleValueAuthenticationParser, null, H2StaticTable.Authorization, H3StaticTable.Authorization);
public static readonly KnownHeader CacheControl = new KnownHeader("Cache-Control", HttpHeaderType.General | HttpHeaderType.NonTrailing, CacheControlHeaderParser.Parser, new string[] { "must-revalidate", "no-cache", "no-store", "no-transform", "private", "proxy-revalidate", "public" }, H2StaticTable.CacheControl, H3StaticTable.CacheControlMaxAge0);
Expand All @@ -47,7 +50,7 @@ internal static class KnownHeaders
public static readonly KnownHeader Expect = new KnownHeader("Expect", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueNameValueWithParametersParser, new string[] { "100-continue" }, H2StaticTable.Expect);
public static readonly KnownHeader ExpectCT = new KnownHeader("Expect-CT");
public static readonly KnownHeader Expires = new KnownHeader("Expires", HttpHeaderType.Content | HttpHeaderType.NonTrailing, DateHeaderParser.Parser, null, H2StaticTable.Expires);
public static readonly KnownHeader From = new KnownHeader("From", HttpHeaderType.Request, GenericHeaderParser.MailAddressParser, null, H2StaticTable.From);
public static readonly KnownHeader From = new KnownHeader("From", HttpHeaderType.Request, MinimalHeaderValidation ? null : GenericHeaderParser.GetMailAddressParser(), null, H2StaticTable.From);
public static readonly KnownHeader GrpcEncoding = new KnownHeader("grpc-encoding", HttpHeaderType.Custom, null, new string[] { "identity", "gzip", "deflate" });
public static readonly KnownHeader GrpcMessage = new KnownHeader("grpc-message");
public static readonly KnownHeader GrpcStatus = new KnownHeader("grpc-status", HttpHeaderType.Custom, null, new string[] { "0" });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Net.Http.Headers;
using System.Text;

using Xunit;

Expand All @@ -17,7 +12,7 @@ public class MailAddressParserTest
[Fact]
public void Properties_ReadValues_MatchExpectation()
{
HttpHeaderParser parser = GenericHeaderParser.MailAddressParser;
HttpHeaderParser parser = GenericHeaderParser.GetMailAddressParser();
Assert.False(parser.SupportsMultipleValues);
Assert.Null(parser.Comparer);
}
Expand Down Expand Up @@ -54,7 +49,7 @@ public void TryParse_SetOfInvalidValueStrings_ReturnsFalse()
private void CheckValidParsedValue(string input, int startIndex, string expectedResult,
int expectedIndex)
{
HttpHeaderParser parser = GenericHeaderParser.MailAddressParser;
HttpHeaderParser parser = GenericHeaderParser.GetMailAddressParser();
object result = null;
Assert.True(parser.TryParseValue(input, null, ref startIndex, out result),
string.Format("TryParse returned false: {0}", input));
Expand All @@ -64,7 +59,7 @@ private void CheckValidParsedValue(string input, int startIndex, string expected

private void CheckInvalidParsedValue(string input, int startIndex)
{
HttpHeaderParser parser = GenericHeaderParser.MailAddressParser;
HttpHeaderParser parser = GenericHeaderParser.GetMailAddressParser();
object result = null;
int newIndex = startIndex;
Assert.False(parser.TryParseValue(input, null, ref newIndex, out result),
Expand Down