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;
|
||||
|
||||
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}
|
||||
{{
|
||||
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
|
||||
_onStarting = null;
|
||||
|
||||
ResponseHeaders.Clear();
|
||||
ResponseHeaders = new FrameResponseHeaders();
|
||||
ResponseHeaders["Content-Length"] = new[] { "0" };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,16 @@ using System.Collections.Generic;
|
|||
|
||||
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
|
||||
{
|
||||
long _bits = 0;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
{
|
||||
private async Task App(Frame frame)
|
||||
{
|
||||
frame.ResponseHeaders.Clear();
|
||||
for (; ;)
|
||||
{
|
||||
var buffer = new byte[8192];
|
||||
|
|
@ -59,6 +60,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
|
||||
private async Task AppChunked(Frame frame)
|
||||
{
|
||||
frame.ResponseHeaders.Clear();
|
||||
var data = new MemoryStream();
|
||||
for (; ;)
|
||||
{
|
||||
|
|
@ -358,6 +360,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
}, null);
|
||||
|
||||
// Anything added to the ResponseHeaders dictionary is ignored
|
||||
frame.ResponseHeaders.Clear();
|
||||
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
||||
throw new Exception();
|
||||
}))
|
||||
|
|
@ -371,12 +374,20 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
await connection.Receive(
|
||||
"HTTP/1.1 500 Internal Server Error",
|
||||
"");
|
||||
await connection.ReceiveStartsWith("Date:");
|
||||
await connection.Receive(
|
||||
"Content-Length: 0",
|
||||
"Server: Kestrel",
|
||||
"",
|
||||
"HTTP/1.1 500 Internal Server Error",
|
||||
"");
|
||||
await connection.ReceiveStartsWith("Date:");
|
||||
await connection.ReceiveEnd(
|
||||
"Content-Length: 0",
|
||||
"Server: Kestrel",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
|
|
@ -399,6 +410,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
return Task.FromResult<object>(null);
|
||||
}, null);
|
||||
|
||||
frame.ResponseHeaders.Clear();
|
||||
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
||||
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
||||
throw new Exception();
|
||||
|
|
@ -434,6 +446,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
|||
return Task.FromResult<object>(null);
|
||||
}, null);
|
||||
|
||||
frame.ResponseHeaders.Clear();
|
||||
frame.ResponseHeaders["Content-Length"] = new[] { "11" };
|
||||
await frame.ResponseBody.WriteAsync(Encoding.ASCII.GetBytes("Hello"), 0, 5);
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
await Receive(lines);
|
||||
|
|
|
|||
Loading…
Reference in New Issue