Properly handle headers with empty values
This commit is contained in:
parent
52f4fa91e3
commit
094b8efbf8
|
|
@ -157,7 +157,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
}
|
||||
}
|
||||
|
||||
while (!terminated && !_requestProcessingStopping && !TakeMessageHeaders(SocketInput))
|
||||
while (!terminated && !_requestProcessingStopping && !TakeMessageHeaders(SocketInput, _requestHeaders))
|
||||
{
|
||||
terminated = SocketInput.RemoteIntakeFin;
|
||||
if (!terminated)
|
||||
|
|
@ -654,7 +654,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
return Encoding.UTF8.GetString(range.Array, range.Offset + startIndex, endIndex - startIndex);
|
||||
}
|
||||
|
||||
private bool TakeMessageHeaders(SocketInput input)
|
||||
public static bool TakeMessageHeaders(SocketInput input, FrameRequestHeaders requestHeaders)
|
||||
{
|
||||
var scan = input.ConsumingStart();
|
||||
var consumed = scan;
|
||||
|
|
@ -692,6 +692,22 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
chSecond == '\r' ||
|
||||
chSecond == '\n')
|
||||
{
|
||||
if (chSecond == '\r')
|
||||
{
|
||||
var scanAhead = scan;
|
||||
var chAhead = scanAhead.Take();
|
||||
if (chAhead == '\n')
|
||||
{
|
||||
chAhead = scanAhead.Take();
|
||||
// If the "\r\n" isn't part of "linear whitespace",
|
||||
// then this header has no value.
|
||||
if (chAhead != ' ' && chAhead != '\t')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
beginValue = scan;
|
||||
chSecond = scan.Take();
|
||||
}
|
||||
|
|
@ -729,9 +745,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
}
|
||||
|
||||
var name = beginName.GetArraySegment(endName);
|
||||
#if DEBUG
|
||||
var nameString = beginName.GetString(endName);
|
||||
#endif
|
||||
var value = beginValue.GetString(endValue);
|
||||
if (wrapping)
|
||||
{
|
||||
|
|
@ -739,7 +752,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
}
|
||||
|
||||
consumed = scan;
|
||||
_requestHeaders.Append(name.Array, name.Offset, name.Count, value);
|
||||
requestHeaders.Append(name.Array, name.Offset, name.Count, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Server.KestrelTests
|
||||
|
|
@ -34,5 +36,34 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
|
||||
Assert.Equal(Encoding.ASCII.GetBytes(expected), beginChunkBytes.ToArray());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Cookie: \r\n\r\n", 1)]
|
||||
[InlineData("Cookie:\r\n\r\n", 1)]
|
||||
[InlineData("Cookie:\r\n value\r\n\r\n", 1)]
|
||||
[InlineData("Cookie\r\n", 0)]
|
||||
[InlineData("Cookie: \r\nConnection: close\r\n\r\n", 2)]
|
||||
[InlineData("Connection: close\r\nCookie: \r\n\r\n", 2)]
|
||||
[InlineData("Connection: close\r\nCookie \r\n", 1)]
|
||||
[InlineData("Connection:\r\n \r\nCookie \r\n", 1)]
|
||||
public void EmptyHeaderValuesCanBeParsed(string rawHeaders, int numHeaders)
|
||||
{
|
||||
var socketInput = new SocketInput(new MemoryPool2());
|
||||
var headerCollection = new FrameRequestHeaders();
|
||||
|
||||
var headerArray = Encoding.ASCII.GetBytes(rawHeaders);
|
||||
var inputBuffer = socketInput.IncomingStart(headerArray.Length);
|
||||
Buffer.BlockCopy(headerArray, 0, inputBuffer.Data.Array, inputBuffer.Data.Offset, headerArray.Length);
|
||||
socketInput.IncomingComplete(headerArray.Length, null);
|
||||
|
||||
var success = Frame.TakeMessageHeaders(socketInput, headerCollection);
|
||||
|
||||
Assert.True(success);
|
||||
Assert.Equal(numHeaders, headerCollection.Count());
|
||||
|
||||
// Assert TakeMessageHeaders consumed all the input
|
||||
var scan = socketInput.ConsumingStart();
|
||||
Assert.True(scan.IsEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue