React to string[] -> StringValues changes.

This commit is contained in:
Chris R 2015-08-28 12:59:00 -07:00
parent 40ca61b640
commit 803ec38073
9 changed files with 434 additions and 426 deletions

View File

@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Framework.Primitives;
// ReSharper disable AccessToModifiedClosure
@ -55,13 +56,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
public string Path { get; set; }
public string QueryString { get; set; }
public string HttpVersion { get; set; }
public IDictionary<string, string[]> RequestHeaders { get; set; }
public IDictionary<string, StringValues> RequestHeaders { get; set; }
public MessageBody MessageBody { get; set; }
public Stream RequestBody { get; set; }
public int StatusCode { get; set; }
public string ReasonPhrase { get; set; }
public IDictionary<string, string[]> ResponseHeaders { get; set; }
public IDictionary<string, StringValues> ResponseHeaders { get; set; }
public Stream ResponseBody { get; set; }
public Stream DuplexStream { get; set; }
@ -357,7 +358,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{
if (_responseStarted) return;
string[] expect;
StringValues expect;
if (HttpVersion.Equals("HTTP/1.1") &&
RequestHeaders.TryGetValue("Expect", out expect) &&
(expect.FirstOrDefault() ?? "").Equals("100-continue", StringComparison.OrdinalIgnoreCase))
@ -444,7 +445,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
private Tuple<ArraySegment<byte>, IDisposable> CreateResponseHeader(
string status,
bool appCompleted,
IEnumerable<KeyValuePair<string, string[]>> headers)
IEnumerable<KeyValuePair<string, StringValues>> headers)
{
var writer = new MemoryPoolTextWriter(Memory);
writer.Write(HttpVersion);

View File

@ -2,36 +2,34 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Framework.Primitives;
namespace Microsoft.AspNet.Server.Kestrel.Http
{
public abstract class FrameHeaders : IDictionary<string, string[]>
public abstract class FrameHeaders : IDictionary<string, StringValues>
{
protected Dictionary<string, string[]> MaybeUnknown;
protected Dictionary<string, StringValues> MaybeUnknown;
protected Dictionary<string, string[]> Unknown => MaybeUnknown ?? (MaybeUnknown = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase));
protected Dictionary<string, StringValues> Unknown => MaybeUnknown ?? (MaybeUnknown = new Dictionary<string, StringValues>(StringComparer.OrdinalIgnoreCase));
protected static string[] AppendValue(string[] existing, string append)
protected static StringValues AppendValue(StringValues existing, string append)
{
var appended = new string[existing.Length + 1];
Array.Copy(existing, appended, existing.Length);
appended[existing.Length] = append;
return appended;
return StringValues.Concat(existing, append);
}
protected virtual int GetCountFast()
{ throw new NotImplementedException(); }
protected virtual string[] GetValueFast(string key)
protected virtual StringValues GetValueFast(string key)
{ throw new NotImplementedException(); }
protected virtual bool TryGetValueFast(string key, out string[] value)
protected virtual bool TryGetValueFast(string key, out StringValues value)
{ throw new NotImplementedException(); }
protected virtual void SetValueFast(string key, string[] value)
protected virtual void SetValueFast(string key, StringValues value)
{ throw new NotImplementedException(); }
protected virtual void AddValueFast(string key, string[] value)
protected virtual void AddValueFast(string key, StringValues value)
{ throw new NotImplementedException(); }
protected virtual bool RemoveFast(string key)
@ -40,14 +38,14 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
protected virtual void ClearFast()
{ throw new NotImplementedException(); }
protected virtual void CopyToFast(KeyValuePair<string, string[]>[] array, int arrayIndex)
protected virtual void CopyToFast(KeyValuePair<string, StringValues>[] array, int arrayIndex)
{ throw new NotImplementedException(); }
protected virtual IEnumerator<KeyValuePair<string, string[]>> GetEnumeratorFast()
protected virtual IEnumerator<KeyValuePair<string, StringValues>> GetEnumeratorFast()
{ throw new NotImplementedException(); }
string[] IDictionary<string, string[]>.this[string key]
StringValues IDictionary<string, StringValues>.this[string key]
{
get
{
@ -60,44 +58,44 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
}
}
int ICollection<KeyValuePair<string, string[]>>.Count => GetCountFast();
int ICollection<KeyValuePair<string, StringValues>>.Count => GetCountFast();
bool ICollection<KeyValuePair<string, string[]>>.IsReadOnly => false;
bool ICollection<KeyValuePair<string, StringValues>>.IsReadOnly => false;
ICollection<string> IDictionary<string, string[]>.Keys => ((IDictionary<string,string[]>)this).Select(x => x.Key).ToList();
ICollection<string> IDictionary<string, StringValues>.Keys => ((IDictionary<string, StringValues>)this).Select(x => x.Key).ToList();
ICollection<string[]> IDictionary<string, string[]>.Values => ((IDictionary<string, string[]>)this).Select(x => x.Value).ToList();
ICollection<StringValues> IDictionary<string, StringValues>.Values => ((IDictionary<string, StringValues>)this).Select(x => x.Value).ToList();
void ICollection<KeyValuePair<string, string[]>>.Add(KeyValuePair<string, string[]> item)
void ICollection<KeyValuePair<string, StringValues>>.Add(KeyValuePair<string, StringValues> item)
{
AddValueFast(item.Key, item.Value);
}
void IDictionary<string, string[]>.Add(string key, string[] value)
void IDictionary<string, StringValues>.Add(string key, StringValues value)
{
AddValueFast(key, value);
}
void ICollection<KeyValuePair<string, string[]>>.Clear()
void ICollection<KeyValuePair<string, StringValues>>.Clear()
{
ClearFast();
}
bool ICollection<KeyValuePair<string, string[]>>.Contains(KeyValuePair<string, string[]> item)
bool ICollection<KeyValuePair<string, StringValues>>.Contains(KeyValuePair<string, StringValues> item)
{
string[] value;
StringValues value;
return
TryGetValueFast(item.Key, out value) &&
object.Equals(value, item.Value);
}
bool IDictionary<string, string[]>.ContainsKey(string key)
bool IDictionary<string, StringValues>.ContainsKey(string key)
{
string[] value;
StringValues value;
return TryGetValueFast(key, out value);
}
void ICollection<KeyValuePair<string, string[]>>.CopyTo(KeyValuePair<string, string[]>[] array, int arrayIndex)
void ICollection<KeyValuePair<string, StringValues>>.CopyTo(KeyValuePair<string, StringValues>[] array, int arrayIndex)
{
CopyToFast(array, arrayIndex);
}
@ -107,26 +105,26 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
return GetEnumeratorFast();
}
IEnumerator<KeyValuePair<string, string[]>> IEnumerable<KeyValuePair<string, string[]>>.GetEnumerator()
IEnumerator<KeyValuePair<string, StringValues>> IEnumerable<KeyValuePair<string, StringValues>>.GetEnumerator()
{
return GetEnumeratorFast();
}
bool ICollection<KeyValuePair<string, string[]>>.Remove(KeyValuePair<string, string[]> item)
bool ICollection<KeyValuePair<string, StringValues>>.Remove(KeyValuePair<string, StringValues> item)
{
string[] value;
StringValues value;
return
TryGetValueFast(item.Key, out value) &&
object.Equals(value, item.Value) &&
RemoveFast(item.Key);
}
bool IDictionary<string, string[]>.Remove(string key)
bool IDictionary<string, StringValues>.Remove(string key)
{
return RemoveFast(key);
}
bool IDictionary<string, string[]>.TryGetValue(string key, out string[] value)
bool IDictionary<string, StringValues>.TryGetValue(string key, out StringValues value)
{
return TryGetValueFast(key, out value);
}
@ -139,33 +137,33 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
return new Enumerator(this);
}
protected override IEnumerator<KeyValuePair<string, string[]>> GetEnumeratorFast()
protected override IEnumerator<KeyValuePair<string, StringValues>> GetEnumeratorFast()
{
return GetEnumerator();
}
public partial struct Enumerator : IEnumerator<KeyValuePair<string, string[]>>
public partial struct Enumerator : IEnumerator<KeyValuePair<string, StringValues>>
{
FrameRequestHeaders _collection;
long _bits;
int _state;
KeyValuePair<string, string[]> _current;
KeyValuePair<string, StringValues> _current;
bool _hasUnknown;
Dictionary<string, string[]>.Enumerator _unknownEnumerator;
Dictionary<string, StringValues>.Enumerator _unknownEnumerator;
internal Enumerator(FrameRequestHeaders collection)
{
_collection = collection;
_bits = collection._bits;
_state = 0;
_current = default(KeyValuePair<string, string[]>);
_current = default(KeyValuePair<string, StringValues>);
_hasUnknown = collection.MaybeUnknown != null;
_unknownEnumerator = _hasUnknown
? collection.MaybeUnknown.GetEnumerator()
: default(Dictionary<string, string[]>.Enumerator);
: default(Dictionary<string, StringValues>.Enumerator);
}
public KeyValuePair<string, string[]> Current => _current;
public KeyValuePair<string, StringValues> Current => _current;
object IEnumerator.Current => _current;
@ -187,33 +185,33 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
return new Enumerator(this);
}
protected override IEnumerator<KeyValuePair<string, string[]>> GetEnumeratorFast()
protected override IEnumerator<KeyValuePair<string, StringValues>> GetEnumeratorFast()
{
return GetEnumerator();
}
public partial struct Enumerator : IEnumerator<KeyValuePair<string, string[]>>
public partial struct Enumerator : IEnumerator<KeyValuePair<string, StringValues>>
{
FrameResponseHeaders _collection;
long _bits;
int _state;
KeyValuePair<string, string[]> _current;
KeyValuePair<string, StringValues> _current;
bool _hasUnknown;
Dictionary<string, string[]>.Enumerator _unknownEnumerator;
Dictionary<string, StringValues>.Enumerator _unknownEnumerator;
internal Enumerator(FrameResponseHeaders collection)
{
_collection = collection;
_bits = collection._bits;
_state = 0;
_current = default(KeyValuePair<string, string[]>);
_current = default(KeyValuePair<string, StringValues>);
_hasUnknown = collection.MaybeUnknown != null;
_unknownEnumerator = _hasUnknown
? collection.MaybeUnknown.GetEnumerator()
: default(Dictionary<string, string[]>.Enumerator);
: default(Dictionary<string, StringValues>.Enumerator);
}
public KeyValuePair<string, string[]> Current => _current;
public KeyValuePair<string, StringValues> Current => _current;
object IEnumerator.Current => _current;

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using Microsoft.Framework.Primitives;
namespace Microsoft.AspNet.Server.Kestrel.Http
{
@ -28,7 +29,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
public static MessageBody For(
string httpVersion,
IDictionary<string, string[]> headers,
IDictionary<string, StringValues> headers,
FrameContext context)
{
// see also http://tools.ietf.org/html/rfc2616#section-4.4
@ -61,15 +62,15 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
return new ForRemainingData(context);
}
public static bool TryGet(IDictionary<string, string[]> headers, string name, out string value)
public static bool TryGet(IDictionary<string, StringValues> headers, string name, out string value)
{
string[] values;
StringValues values;
if (!headers.TryGetValue(name, out values) || values == null)
{
value = null;
return false;
}
var count = values.Length;
var count = values.Count;
if (count == 0)
{
value = null;

View File

@ -8,6 +8,7 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.Framework.Primitives;
namespace Microsoft.AspNet.Server.Kestrel
{
@ -115,7 +116,7 @@ namespace Microsoft.AspNet.Server.Kestrel
}
}
IDictionary<string, string[]> IHttpRequestFeature.Headers
IDictionary<string, StringValues> IHttpRequestFeature.Headers
{
get
{
@ -167,7 +168,7 @@ namespace Microsoft.AspNet.Server.Kestrel
}
}
IDictionary<string, string[]> IHttpResponseFeature.Headers
IDictionary<string, StringValues> IHttpResponseFeature.Headers
{
get
{
@ -212,7 +213,7 @@ namespace Microsoft.AspNet.Server.Kestrel
{
get
{
string[] values;
StringValues values;
if (_frame.RequestHeaders.TryGetValue("Connection", out values))
{
return values.Any(value => value.IndexOf("upgrade", StringComparison.OrdinalIgnoreCase) != -1);
@ -225,10 +226,10 @@ namespace Microsoft.AspNet.Server.Kestrel
{
_frame.StatusCode = 101;
_frame.ReasonPhrase = "Switching Protocols";
_frame.ResponseHeaders["Connection"] = new string[] { "Upgrade" };
_frame.ResponseHeaders["Connection"] = "Upgrade";
if (!_frame.ResponseHeaders.ContainsKey("Upgrade"))
{
string[] values;
StringValues values;
if (_frame.RequestHeaders.TryGetValue("Upgrade", out values))
{
_frame.ResponseHeaders["Upgrade"] = values;

View File

@ -1,7 +1,7 @@
using Microsoft.AspNet.Server.Kestrel.Http;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.Framework.Primitives;
using Xunit;
namespace Microsoft.AspNet.Server.KestrelTests
@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void InitialDictionaryIsEmpty()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
Assert.Equal(0, headers.Count);
Assert.False(headers.IsReadOnly);
@ -20,31 +20,31 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void SettingUnknownHeadersWorks()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
headers["custom"] = new[] { "value" };
Assert.NotNull(headers["custom"]);
Assert.Equal(1, headers["custom"].Length);
Assert.Equal(1, headers["custom"].Count);
Assert.Equal("value", headers["custom"][0]);
}
[Fact]
public void SettingKnownHeadersWorks()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
headers["host"] = new[] { "value" };
Assert.NotNull(headers["host"]);
Assert.Equal(1, headers["host"].Length);
Assert.Equal(1, headers["host"].Count);
Assert.Equal("value", headers["host"][0]);
}
[Fact]
public void KnownAndCustomHeaderCountAddedTogether()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
headers["host"] = new[] { "value" };
headers["custom"] = new[] { "value" };
@ -55,9 +55,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void TryGetValueWorksForKnownAndUnknownHeaders()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
string[] value;
StringValues value;
Assert.False(headers.TryGetValue("host", out value));
Assert.False(headers.TryGetValue("custom", out value));
@ -73,7 +73,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void SameExceptionThrownForMissingKey()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
Assert.Throws<KeyNotFoundException>(() => headers["custom"]);
Assert.Throws<KeyNotFoundException>(() => headers["host"]);
@ -82,7 +82,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void EntriesCanBeEnumerated()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
var v1 = new[] { "localhost" };
var v2 = new[] { "value" };
headers["host"] = v1;
@ -90,8 +90,8 @@ namespace Microsoft.AspNet.Server.KestrelTests
Assert.Equal(
new[] {
new KeyValuePair<string, string[]>("Host", v1),
new KeyValuePair<string, string[]>("custom", v2),
new KeyValuePair<string, StringValues>("Host", v1),
new KeyValuePair<string, StringValues>("custom", v2),
},
headers);
}
@ -99,9 +99,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void KeysAndValuesCanBeEnumerated()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
var v1 = new[] { "localhost" };
var v2 = new[] { "value" };
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
StringValues v1 = new[] { "localhost" };
StringValues v2 = new[] { "value" };
headers["host"] = v1;
headers["custom"] = v2;
@ -109,7 +109,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
new[] { "Host", "custom" },
headers.Keys);
Assert.Equal<string[]>(
Assert.Equal<StringValues>(
new[] { v1, v2 },
headers.Values);
}
@ -118,11 +118,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void ContainsAndContainsKeyWork()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
var kv1 = new KeyValuePair<string, string[]>("host", new[] { "localhost" });
var kv2 = new KeyValuePair<string, string[]>("custom", new[] { "value" });
var kv1b = new KeyValuePair<string, string[]>("host", new[] { "localhost" });
var kv2b = new KeyValuePair<string, string[]>("custom", new[] { "value" });
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
var kv1 = new KeyValuePair<string, StringValues>("host", new[] { "localhost" });
var kv2 = new KeyValuePair<string, StringValues>("custom", new[] { "value" });
var kv1b = new KeyValuePair<string, StringValues>("host", new[] { "localhost" });
var kv2b = new KeyValuePair<string, StringValues>("custom", new[] { "value" });
Assert.False(headers.ContainsKey("host"));
Assert.False(headers.ContainsKey("custom"));
@ -149,9 +149,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void AddWorksLikeSetAndThrowsIfKeyExists()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
string[] value;
StringValues value;
Assert.False(headers.TryGetValue("host", out value));
Assert.False(headers.TryGetValue("custom", out value));
@ -169,11 +169,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void ClearRemovesAllHeaders()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
headers.Add("host", new[] { "localhost" });
headers.Add("custom", new[] { "value" });
string[] value;
StringValues value;
Assert.Equal(2, headers.Count);
Assert.True(headers.TryGetValue("host", out value));
Assert.True(headers.TryGetValue("custom", out value));
@ -188,11 +188,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void RemoveTakesHeadersOutOfDictionary()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
headers.Add("host", new[] { "localhost" });
headers.Add("custom", new[] { "value" });
string[] value;
StringValues value;
Assert.Equal(2, headers.Count);
Assert.True(headers.TryGetValue("host", out value));
Assert.True(headers.TryGetValue("custom", out value));
@ -215,24 +215,24 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void CopyToMovesDataIntoArray()
{
IDictionary<string, string[]> headers = new FrameRequestHeaders();
IDictionary<string, StringValues> headers = new FrameRequestHeaders();
headers.Add("host", new[] { "localhost" });
headers.Add("custom", new[] { "value" });
var entries = new KeyValuePair<string, string[]>[4];
var entries = new KeyValuePair<string, StringValues>[4];
headers.CopyTo(entries, 1);
Assert.Null(entries[0].Key);
Assert.Null(entries[0].Value);
Assert.Equal(new StringValues(), entries[0].Value);
Assert.Equal("Host", entries[1].Key);
Assert.NotNull(entries[1].Value);
Assert.Equal(new[] { "localhost" }, entries[1].Value);
Assert.Equal("custom", entries[2].Key);
Assert.NotNull(entries[2].Value);
Assert.Equal(new[] { "value" }, entries[2].Value);
Assert.Null(entries[3].Key);
Assert.Null(entries[3].Value);
Assert.Equal(new StringValues(), entries[0].Value);
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.Framework.Primitives;
using Xunit;
namespace Microsoft.AspNet.Server.KestrelTests
@ -13,19 +14,19 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void InitialDictionaryContainsServerAndDate()
{
IDictionary<string, string[]> headers = new FrameResponseHeaders();
IDictionary<string, StringValues> headers = new FrameResponseHeaders();
Assert.Equal(2, headers.Count);
string[] serverHeader;
StringValues serverHeader;
Assert.True(headers.TryGetValue("Server", out serverHeader));
Assert.Equal(1, serverHeader.Length);
Assert.Equal(1, serverHeader.Count);
Assert.Equal("Kestrel", serverHeader[0]);
string[] dateHeader;
StringValues dateHeader;
DateTime date;
Assert.True(headers.TryGetValue("Date", out dateHeader));
Assert.Equal(1, dateHeader.Length);
Assert.Equal(1, dateHeader.Count);
Assert.True(DateTime.TryParse(dateHeader[0], out date));
Assert.True(DateTime.Now - date <= TimeSpan.FromMinutes(1));
@ -35,7 +36,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public void InitialEntriesCanBeCleared()
{
IDictionary<string, string[]> headers = new FrameResponseHeaders();
IDictionary<string, StringValues> headers = new FrameResponseHeaders();
headers.Clear();

View File

@ -1,11 +1,12 @@
// 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.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.Framework.Primitives;
using Xunit;
namespace Microsoft.AspNet.Server.KestrelTests
@ -19,7 +20,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
public void Http10ConnectionClose()
{
var input = new TestInput();
var body = MessageBody.For("HTTP/1.0", new Dictionary<string, string[]>(), input.FrameContext);
var body = MessageBody.For("HTTP/1.0", new Dictionary<string, StringValues>(), input.FrameContext);
var stream = new FrameRequestStream(body);
input.Add("Hello", true);
@ -38,7 +39,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
public async Task Http10ConnectionCloseAsync()
{
var input = new TestInput();
var body = MessageBody.For("HTTP/1.0", new Dictionary<string, string[]>(), input.FrameContext);
var body = MessageBody.For("HTTP/1.0", new Dictionary<string, StringValues>(), input.FrameContext);
var stream = new FrameRequestStream(body);
input.Add("Hello", true);

View File

@ -167,6 +167,7 @@ namespace Microsoft.AspNet.Server.Kestrel.GeneratedCode
return $@"
using System;
using System.Collections.Generic;
using Microsoft.Framework.Primitives;
namespace Microsoft.AspNet.Server.Kestrel.Http
{{
@ -174,8 +175,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{{
public FrameResponseHeaders()
{{
_Server = new[] {{ ""Kestrel"" }};
_Date = new[] {{ DateTime.UtcNow.ToString(""r"") }};
_Server = ""Kestrel"";
_Date = DateTime.UtcNow.ToString(""r"");
_bits = {
1L << responseHeaders.First(header => header.Name == "Server").Index |
1L << responseHeaders.First(header => header.Name == "Date").Index
@ -187,7 +188,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{{
long _bits = 0;
{Each(loop.Headers, header => @"
string[] _" + header.Identifier + ";")}
StringValues _" + header.Identifier + ";")}
protected override int GetCountFast()
{{
@ -201,7 +202,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
return count;
}}
protected override string[] GetValueFast(string key)
protected override StringValues GetValueFast(string key)
{{
switch(key.Length)
{{{Each(loop.HeadersByLength, byLength => $@"
@ -228,7 +229,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
return MaybeUnknown[key];
}}
protected override bool TryGetValueFast(string key, out string[] value)
protected override bool TryGetValueFast(string key, out StringValues value)
{{
switch(key.Length)
{{{Each(loop.HeadersByLength, byLength => $@"
@ -243,18 +244,18 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
}}
else
{{
value = null;
value = StringValues.Empty;
return false;
}}
}}
")}}}
break;
")}}}
value = null;
value = StringValues.Empty;
return MaybeUnknown?.TryGetValue(key, out value) ?? false;
}}
protected override void SetValueFast(string key, string[] value)
protected override void SetValueFast(string key, StringValues value)
{{
switch(key.Length)
{{{Each(loop.HeadersByLength, byLength => $@"
@ -272,7 +273,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
Unknown[key] = value;
}}
protected override void AddValueFast(string key, string[] value)
protected override void AddValueFast(string key, StringValues value)
{{
switch(key.Length)
{{{Each(loop.HeadersByLength, byLength => $@"
@ -324,7 +325,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
MaybeUnknown?.Clear();
}}
protected override void CopyToFast(KeyValuePair<string, string[]>[] array, int arrayIndex)
protected override void CopyToFast(KeyValuePair<string, StringValues>[] array, int arrayIndex)
{{
if (arrayIndex < 0)
{{
@ -339,11 +340,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
throw new ArgumentException();
}}
array[arrayIndex] = new KeyValuePair<string, string[]>(""{header.Name}"", _{header.Identifier});
array[arrayIndex] = new KeyValuePair<string, StringValues>(""{header.Name}"", _{header.Identifier});
++arrayIndex;
}}
")}
((ICollection<KeyValuePair<string, string[]>>)MaybeUnknown)?.CopyTo(array, arrayIndex);
((ICollection<KeyValuePair<string, StringValues>>)MaybeUnknown)?.CopyTo(array, arrayIndex);
}}
public unsafe void Append(byte[] keyBytes, int keyOffset, int keyLength, string value)
@ -370,8 +371,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
break;
")}}}}}
var key = System.Text.Encoding.ASCII.GetString(keyBytes, keyOffset, keyLength);
string[] existing;
Unknown[key] = Unknown.TryGetValue(key, out existing) ? AppendValue(existing, value) : new[] {{value}};
StringValues existing;
Unknown.TryGetValue(key, out existing);
Unknown[key] = AppendValue(existing, value);
}}
public partial struct Enumerator
@ -391,7 +393,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
state{header.Index}:
if ({header.TestBit()})
{{
_current = new KeyValuePair<string, string[]>(""{header.Name}"", _collection._{header.Identifier});
_current = new KeyValuePair<string, StringValues>(""{header.Name}"", _collection._{header.Identifier});
_state = {header.Index + 1};
return true;
}}
@ -399,7 +401,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
state_default:
if (!_hasUnknown || !_unknownEnumerator.MoveNext())
{{
_current = default(KeyValuePair<string, string[]>);
_current = default(KeyValuePair<string, StringValues>);
return false;
}}
_current = _unknownEnumerator.Current;