Include Server and Date in the initial response header dictionary
This commit is contained in:
parent
978dd39924
commit
e5144e3139
|
|
@ -170,7 +170,20 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel.Http
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{{{Each(loops, loop => $@"
|
{{
|
||||||
|
public partial class FrameResponseHeaders
|
||||||
|
{{
|
||||||
|
public FrameResponseHeaders()
|
||||||
|
{{
|
||||||
|
_Server = new[] {{ ""Kestrel"" }};
|
||||||
|
_Date = new[] {{ DateTime.UtcNow.ToString(""r"") }};
|
||||||
|
_bits = {
|
||||||
|
1L << responseHeaders.First(header => header.Name == "Server").Index |
|
||||||
|
1L << responseHeaders.First(header => header.Name == "Date").Index
|
||||||
|
}L;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
{Each(loops, loop => $@"
|
||||||
public partial class {loop.ClassName}
|
public partial class {loop.ClassName}
|
||||||
{{
|
{{
|
||||||
long _bits = 0;
|
long _bits = 0;
|
||||||
|
|
|
||||||
|
|
@ -338,7 +338,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
// the app func has failed. https://github.com/aspnet/KestrelHttpServer/issues/43
|
// the app func has failed. https://github.com/aspnet/KestrelHttpServer/issues/43
|
||||||
_onStarting = null;
|
_onStarting = null;
|
||||||
|
|
||||||
ResponseHeaders.Clear();
|
ResponseHeaders = new FrameResponseHeaders();
|
||||||
ResponseHeaders["Content-Length"] = new[] { "0" };
|
ResponseHeaders["Content-Length"] = new[] { "0" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,16 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel.Http
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
|
public partial class FrameResponseHeaders
|
||||||
|
{
|
||||||
|
public FrameResponseHeaders()
|
||||||
|
{
|
||||||
|
_Server = new[] { "Kestrel" };
|
||||||
|
_Date = new[] { DateTime.UtcNow.ToString("r") };
|
||||||
|
_bits = 67108868L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public partial class FrameRequestHeaders
|
public partial class FrameRequestHeaders
|
||||||
{
|
{
|
||||||
long _bits = 0;
|
long _bits = 0;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
{
|
{
|
||||||
private async Task App(Frame frame)
|
private async Task App(Frame frame)
|
||||||
{
|
{
|
||||||
|
frame.ResponseHeaders.Clear();
|
||||||
for (; ;)
|
for (; ;)
|
||||||
{
|
{
|
||||||
var buffer = new byte[8192];
|
var buffer = new byte[8192];
|
||||||
|
|
@ -59,6 +60,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
|
|
||||||
private async Task AppChunked(Frame frame)
|
private async Task AppChunked(Frame frame)
|
||||||
{
|
{
|
||||||
|
frame.ResponseHeaders.Clear();
|
||||||
var data = new MemoryStream();
|
var data = new MemoryStream();
|
||||||
for (; ;)
|
for (; ;)
|
||||||
{
|
{
|
||||||
|
|
@ -358,6 +360,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
// Anything added to the ResponseHeaders dictionary is ignored
|
// Anything added to the ResponseHeaders dictionary is ignored
|
||||||
|
frame.ResponseHeaders.Clear();
|
||||||
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}))
|
}))
|
||||||
|
|
@ -371,12 +374,20 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.Receive(
|
||||||
"HTTP/1.1 500 Internal Server Error",
|
"HTTP/1.1 500 Internal Server Error",
|
||||||
|
"");
|
||||||
|
await connection.ReceiveStartsWith("Date:");
|
||||||
|
await connection.Receive(
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
|
"Server: Kestrel",
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 500 Internal Server Error",
|
"HTTP/1.1 500 Internal Server Error",
|
||||||
|
"");
|
||||||
|
await connection.ReceiveStartsWith("Date:");
|
||||||
|
await connection.ReceiveEnd(
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
|
"Server: Kestrel",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -399,6 +410,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
return Task.FromResult<object>(null);
|
return Task.FromResult<object>(null);
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
|
frame.ResponseHeaders.Clear();
|
||||||
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
||||||
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
|
|
@ -434,6 +446,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
return Task.FromResult<object>(null);
|
return Task.FromResult<object>(null);
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
|
frame.ResponseHeaders.Clear();
|
||||||
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
||||||
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Hello"), 0, 5);
|
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Hello"), 0, 5);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
// 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 System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
|
{
|
||||||
|
public class FrameResponseHeadersTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void InitialDictionaryContainsServerAndDate()
|
||||||
|
{
|
||||||
|
IDictionary<string, string[]> headers = new FrameResponseHeaders();
|
||||||
|
|
||||||
|
Assert.Equal(2, headers.Count);
|
||||||
|
|
||||||
|
string[] serverHeader;
|
||||||
|
Assert.True(headers.TryGetValue("Server", out serverHeader));
|
||||||
|
Assert.Equal(1, serverHeader.Length);
|
||||||
|
Assert.Equal("Kestrel", serverHeader[0]);
|
||||||
|
|
||||||
|
string[] dateHeader;
|
||||||
|
DateTime date;
|
||||||
|
Assert.True(headers.TryGetValue("Date", out dateHeader));
|
||||||
|
Assert.Equal(1, dateHeader.Length);
|
||||||
|
Assert.True(DateTime.TryParse(dateHeader[0], out date));
|
||||||
|
Assert.True(DateTime.Now - date <= TimeSpan.FromMinutes(1));
|
||||||
|
|
||||||
|
Assert.False(headers.IsReadOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InitialEntriesCanBeCleared()
|
||||||
|
{
|
||||||
|
IDictionary<string, string[]> headers = new FrameResponseHeaders();
|
||||||
|
|
||||||
|
headers.Clear();
|
||||||
|
|
||||||
|
Assert.Equal(0, headers.Count);
|
||||||
|
Assert.False(headers.ContainsKey("Server"));
|
||||||
|
Assert.False(headers.ContainsKey("Date"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -84,6 +84,38 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
Assert.Equal(expected, new String(actual, 0, offset));
|
Assert.Equal(expected, new String(actual, 0, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ReceiveStartsWith(string prefix, int maxLineLength = 1024)
|
||||||
|
{
|
||||||
|
var actual = new char[maxLineLength];
|
||||||
|
var offset = 0;
|
||||||
|
|
||||||
|
while (offset < maxLineLength)
|
||||||
|
{
|
||||||
|
// Read one char at a time so we don't read past the end of the line.
|
||||||
|
var task = _reader.ReadAsync(actual, offset, 1);
|
||||||
|
if (!Debugger.IsAttached)
|
||||||
|
{
|
||||||
|
Assert.True(task.Wait(1000), "timeout");
|
||||||
|
}
|
||||||
|
var count = await task;
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.True(count == 1);
|
||||||
|
offset++;
|
||||||
|
|
||||||
|
if (actual[offset - 1] == '\n')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var actualLine = new string(actual, 0, offset);
|
||||||
|
Assert.StartsWith(prefix, actualLine);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task ReceiveEnd(params string[] lines)
|
public async Task ReceiveEnd(params string[] lines)
|
||||||
{
|
{
|
||||||
await Receive(lines);
|
await Receive(lines);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue