Using the optimized method for converting header name to ASCII

This commit is contained in:
moozzyk 2016-05-27 11:03:05 -07:00
parent de022b6051
commit 0342754c57
5 changed files with 499 additions and 451 deletions

View File

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Server.Kestrel.Exceptions;
using Microsoft.AspNetCore.Server.Kestrel.Infrastructure;
using Microsoft.Extensions.Primitives;
@ -4198,6 +4198,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
public unsafe void Append(byte[] keyBytes, int keyOffset, int keyLength, string value)
{
var key = new string('\0', keyLength);
fixed (byte* ptr = &keyBytes[keyOffset])
{
var pUB = ptr;
@ -4898,8 +4899,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
}
break;
}
fixed(char *keyBuffer = key)
{
if (!AsciiUtilities.TryGetAsciiString(ptr, keyBuffer, keyLength))
{
throw new BadHttpRequestException("Invalid characters in header name");
}
var key = System.Text.Encoding.ASCII.GetString(keyBytes, keyOffset, keyLength);
}
}
StringValues existing;
Unknown.TryGetValue(key, out existing);
Unknown[key] = AppendValue(existing, value);

View File

@ -172,6 +172,23 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
}
}
[Fact]
public async Task BadRequestWhenNameHeaderNamesContainsNonASCIICharacters()
{
using (var server = new TestServer(context => { return Task.FromResult(0); }))
{
using (var connection = server.CreateConnection())
{
await connection.SendEnd(
"GET / HTTP/1.1",
"Hëädër: value",
"",
"");
await ReceiveBadRequestResponse(connection);
}
}
}
private async Task ReceiveBadRequestResponse(TestConnection connection)
{
await connection.Receive(

View File

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Server.Kestrel.Exceptions;
using Microsoft.AspNetCore.Server.Kestrel.Http;
using Microsoft.Extensions.Primitives;
using Xunit;
@ -233,5 +235,16 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
Assert.Null(entries[3].Key);
Assert.Equal(new StringValues(), entries[0].Value);
}
[Fact]
public void AppendThrowsWhenHeaderValueContainsNonASCIICharacters()
{
var headers = new FrameRequestHeaders();
const string key = "\u00141ód\017c";
var encoding = Encoding.GetEncoding("iso-8859-1");
Assert.Throws<BadHttpRequestException>(
() => headers.Append(encoding.GetBytes(key), 0, encoding.GetByteCount(key), key));
}
}
}

View File

@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
public async Task Send(params string[] lines)
{
var text = String.Join("\r\n", lines);
var writer = new StreamWriter(_stream, Encoding.ASCII);
var writer = new StreamWriter(_stream, Encoding.GetEncoding("iso-8859-1"));
for (var index = 0; index < text.Length; index++)
{
var ch = text[index];

View File

@ -199,7 +199,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.GeneratedCode
return $@"
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Server.Kestrel.Exceptions;
using Microsoft.AspNetCore.Server.Kestrel.Infrastructure;
using Microsoft.Extensions.Primitives;
@ -418,6 +418,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
{(loop.ClassName == "FrameRequestHeaders" ? $@"
public unsafe void Append(byte[] keyBytes, int keyOffset, int keyLength, string value)
{{
var key = new string('\0', keyLength);
fixed (byte* ptr = &keyBytes[keyOffset])
{{
var pUB = ptr;
@ -445,8 +446,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
")}}}
break;
")}}}
fixed(char *keyBuffer = key)
{{
if (!AsciiUtilities.TryGetAsciiString(ptr, keyBuffer, keyLength))
{{
throw new BadHttpRequestException(""Invalid characters in header name"");
}}
var key = System.Text.Encoding.ASCII.GetString(keyBytes, keyOffset, keyLength);
}}
}}
StringValues existing;
Unknown.TryGetValue(key, out existing);
Unknown[key] = AppendValue(existing, value);