RO Headers & rationalise exceptions

This commit is contained in:
Ben Adams 2016-02-13 03:35:26 +00:00
parent c293bbbd1a
commit 460dbb15c2
4 changed files with 308 additions and 849 deletions

View File

@ -656,8 +656,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
byte[] statusBytes,
bool appCompleted)
{
var end = SocketOutput.ProducingStart();
var responseHeaders = _frameHeaders.ResponseHeaders;
responseHeaders.SetReadOnly();
var end = SocketOutput.ProducingStart();
if (_keepAlive)
{
foreach (var connectionValue in responseHeaders.HeaderConnection)

View File

@ -12,6 +12,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
{
public abstract class FrameHeaders : IHeaderDictionary
{
protected bool _isReadOnly;
protected Dictionary<string, StringValues> MaybeUnknown;
protected Dictionary<string, StringValues> Unknown => MaybeUnknown ?? (MaybeUnknown = new Dictionary<string, StringValues>(StringComparer.OrdinalIgnoreCase));
@ -26,6 +27,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
}
set
{
if (_isReadOnly)
{
ThrowReadOnlyException();
}
SetValueFast(key, value);
}
}
@ -38,20 +43,50 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
}
set
{
if (_isReadOnly)
{
ThrowReadOnlyException();
}
SetValueFast(key, value);
}
}
protected void ThrowReadOnlyException()
{
throw new InvalidOperationException("Headers are readonly, reponse has already started.");
}
protected void ThrowArgumentException()
{
throw new ArgumentException();
}
protected void ThrowKeyNotFoundException()
{
throw new KeyNotFoundException();
}
protected void ThrowDuplicateKeyException()
{
throw new ArgumentException("An item with the same key has already been added.");
}
int ICollection<KeyValuePair<string, StringValues>>.Count => GetCountFast();
bool ICollection<KeyValuePair<string, StringValues>>.IsReadOnly => false;
bool ICollection<KeyValuePair<string, StringValues>>.IsReadOnly => _isReadOnly;
ICollection<string> IDictionary<string, StringValues>.Keys => ((IDictionary<string, StringValues>)this).Select(pair => pair.Key).ToList();
ICollection<StringValues> IDictionary<string, StringValues>.Values => ((IDictionary<string, StringValues>)this).Select(pair => pair.Value).ToList();
public void SetReadOnly()
{
_isReadOnly = true;
}
public void Reset()
{
_isReadOnly = false;
ClearFast();
}
@ -105,16 +140,28 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
void ICollection<KeyValuePair<string, StringValues>>.Add(KeyValuePair<string, StringValues> item)
{
if (_isReadOnly)
{
ThrowReadOnlyException();
}
AddValueFast(item.Key, item.Value);
}
void IDictionary<string, StringValues>.Add(string key, StringValues value)
{
if (_isReadOnly)
{
ThrowReadOnlyException();
}
AddValueFast(key, value);
}
void ICollection<KeyValuePair<string, StringValues>>.Clear()
{
if (_isReadOnly)
{
ThrowReadOnlyException();
}
ClearFast();
}
@ -158,6 +205,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
bool IDictionary<string, StringValues>.Remove(string key)
{
if (_isReadOnly)
{
ThrowReadOnlyException();
}
return RemoveFast(key);
}

View File

@ -263,7 +263,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
}}
else
{{
throw new System.Collections.Generic.KeyNotFoundException();
ThrowKeyNotFoundException();
}}
}}
")}}}
@ -271,7 +271,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
")}}}
if (MaybeUnknown == null)
{{
throw new System.Collections.Generic.KeyNotFoundException();
ThrowKeyNotFoundException();
}}
return MaybeUnknown[key];
}}
@ -328,7 +328,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
{{
if ({header.TestBit()})
{{
throw new ArgumentException(""An item with the same key has already been added."");
ThrowDuplicateKeyException();
}}
{header.SetBit()};
_{header.Identifier} = value;{(header.EnhancedSetter == false ? "" : $@"
@ -377,14 +377,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
{{
if (arrayIndex < 0)
{{
throw new ArgumentException();
ThrowArgumentException();
}}
{Each(loop.Headers, header => $@"
if ({header.TestBit()})
{{
if (arrayIndex == array.Length)
{{
throw new ArgumentException();
ThrowArgumentException();
}}
array[arrayIndex] = new KeyValuePair<string, StringValues>(""{header.Name}"", _{header.Identifier});
@ -415,6 +415,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
}}
")}
}}" : "")}
{(loop.ClassName == "FrameRequestHeaders" ? $@"
public unsafe void Append(byte[] keyBytes, int keyOffset, int keyLength, string value)
{{
fixed (byte* ptr = &keyBytes[keyOffset])
@ -449,7 +450,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
StringValues existing;
Unknown.TryGetValue(key, out existing);
Unknown[key] = AppendValue(existing, value);
}}
}}" : "")}
public partial struct Enumerator
{{
public bool MoveNext()