{
for (int i = 0; i < knownValues.Length; i++)
{
- if (ByteArrayHelpers.EqualsOrdinalAsciiIgnoreCase(knownValues[i], headerValue))
+ if (ByteArrayHelpers.EqualsOrdinalAscii(knownValues[i], headerValue))
{
return knownValues[i];
}
switch (contentTypeValue.Length)
{
case 8:
- switch (contentTypeValue[7] | 0x20)
+ switch (contentTypeValue[7])
{
- case 'l': candidate = "text/xml"; break; // text/xm[l]
- case 's': candidate = "text/css"; break; // text/cs[s]
- case 'v': candidate = "text/csv"; break; // text/cs[v]
+ case (byte)'l': candidate = "text/xml"; break; // text/xm[l]
+ case (byte)'s': candidate = "text/css"; break; // text/cs[s]
+ case (byte)'v': candidate = "text/csv"; break; // text/cs[v]
}
break;
case 9:
- switch (contentTypeValue[6] | 0x20)
+ switch (contentTypeValue[6])
{
- case 'g': candidate = "image/gif"; break; // image/[g]if
- case 'p': candidate = "image/png"; break; // image/[p]ng
- case 't': candidate = "text/html"; break; // text/h[t]ml
+ case (byte)'g': candidate = "image/gif"; break; // image/[g]if
+ case (byte)'p': candidate = "image/png"; break; // image/[p]ng
+ case (byte)'t': candidate = "text/html"; break; // text/h[t]ml
}
break;
case 10:
- switch (contentTypeValue[0] | 0x20)
+ switch (contentTypeValue[0])
{
- case 't': candidate = "text/plain"; break; // [t]ext/plain
- case 'i': candidate = "image/jpeg"; break; // [i]mage/jpeg
+ case (byte)'t': candidate = "text/plain"; break; // [t]ext/plain
+ case (byte)'i': candidate = "image/jpeg"; break; // [i]mage/jpeg
}
break;
case 15:
- switch (contentTypeValue[12] | 0x20)
+ switch (contentTypeValue[12])
{
- case 'p': candidate = "application/pdf"; break; // application/[p]df
- case 'x': candidate = "application/xml"; break; // application/[x]ml
- case 'z': candidate = "application/zip"; break; // application/[z]ip
+ case (byte)'p': candidate = "application/pdf"; break; // application/[p]df
+ case (byte)'x': candidate = "application/xml"; break; // application/[x]ml
+ case (byte)'z': candidate = "application/zip"; break; // application/[z]ip
}
break;
case 16:
- switch (contentTypeValue[12] | 0x20)
+ switch (contentTypeValue[12])
{
- case 'g': candidate = "application/grpc"; break; // application/[g]rpc
- case 'j': candidate = "application/json"; break; // application/[j]son
+ case (byte)'g': candidate = "application/grpc"; break; // application/[g]rpc
+ case (byte)'j': candidate = "application/json"; break; // application/[j]son
}
break;
break;
case 24:
- switch (contentTypeValue[0] | 0x20)
+ switch (contentTypeValue[19])
{
- case 'a': candidate = "application/octet-stream"; break; // application/octet-stream
- case 't': candidate = "text/html; charset=utf-8"; break; // text/html; charset=utf-8
+ case (byte)'t': candidate = "application/octet-stream"; break; // application/octet-s[t]ream
+ case (byte)'u': candidate = "text/html; charset=utf-8"; break; // text/html; charset=[u]tf-8
+ case (byte)'U': candidate = "text/html; charset=UTF-8"; break; // text/html; charset=[U]TF-8
}
break;
Debug.Assert(candidate is null || candidate.Length == contentTypeValue.Length);
- return candidate != null && ByteArrayHelpers.EqualsOrdinalAsciiIgnoreCase(candidate, contentTypeValue) ?
+ return candidate != null && ByteArrayHelpers.EqualsOrdinalAscii(candidate, contentTypeValue) ?
candidate :
null;
}
[InlineData("Content-Type", "application/javascript")]
[InlineData("Content-Type", "application/octet-stream")]
[InlineData("Content-Type", "text/html; charset=utf-8")]
+ [InlineData("Content-Type", "text/html; charset=UTF-8")]
[InlineData("Content-Type", "text/plain; charset=utf-8")]
[InlineData("Content-Type", "application/json; charset=utf-8")]
[InlineData("Content-Type", "application/x-www-form-urlencoded")]
[InlineData("X-XSS-Protection", "1; mode=block")]
public void GetKnownHeaderValue_Known_Found(string name, string value)
{
- foreach (string casedValue in new[] { value, value.ToUpperInvariant(), value.ToLowerInvariant() })
+ KnownHeader knownHeader = KnownHeaders.TryGetKnownHeader(name);
+ Assert.NotNull(knownHeader);
+
+ string v1 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null);
+ Assert.NotNull(v1);
+ Assert.Equal(value, v1);
+
+ string v2 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null);
+ Assert.Same(v1, v2);
+
+ if (TryChangeCasing(value, out string newValue)) // Doesn't make sense for values that are just numbers
{
- Validate(KnownHeaders.TryGetKnownHeader(name), casedValue);
+ GetKnownHeaderValue_Unknown_NotFound(name, newValue);
}
- static void Validate(KnownHeader knownHeader, string value)
+ static bool TryChangeCasing(string value, out string newValue)
{
- Assert.NotNull(knownHeader);
+ string upper = value.ToUpperInvariant();
+ if (upper != value)
+ {
+ newValue = upper;
+ return true;
+ }
- string v1 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null);
- Assert.NotNull(v1);
- Assert.Equal(value, v1, StringComparer.OrdinalIgnoreCase);
+ string lower = value.ToLowerInvariant();
+ if (lower != value)
+ {
+ newValue = lower;
+ return true;
+ }
- string v2 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null);
- Assert.Same(v1, v2);
+ newValue = null;
+ return false;
}
}
[Theory]
[InlineData("Content-Type", "application/jsot")]
[InlineData("Content-Type", "application/jsons")]
+ [InlineData("Transfer-Encoding", "foo")]
public void GetKnownHeaderValue_Unknown_NotFound(string name, string value)
{
KnownHeader knownHeader = KnownHeaders.TryGetKnownHeader(name);