Test: Added a new MiddleWare to test the Gracefulshutdown message (#233)

Added TestMiddleWare to handle the Gracefulshutdown message instead of IISMiddleware
This commit is contained in:
jhkimnew 2017-11-06 13:47:59 -08:00 committed by GitHub
parent c315b27ad9
commit 13312109ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 30 deletions

View File

@ -0,0 +1,31 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.IISIntegration;
namespace AspnetCoreModule.TestSites.Standard
{
internal class IISSetupFilter : IStartupFilter
{
private readonly string _pairingToken;
internal IISSetupFilter(string pairingToken)
{
_pairingToken = pairingToken;
}
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return app =>
{
app.UseMiddleware<TestMiddleWareBeforeIISMiddleWare>();
app.UseMiddleware<IISMiddleware>(_pairingToken);
next(app);
};
}
}
}

View File

@ -2,13 +2,13 @@
// Licensed under the MIT License. See License.txt in the project root for license information. // Licensed under the MIT License. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using System; using System;
using System.IO; using System.IO;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using System.Net; using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace AspnetCoreModule.TestSites.Standard namespace AspnetCoreModule.TestSites.Standard
{ {
@ -88,8 +88,15 @@ namespace AspnetCoreModule.TestSites.Standard
else else
{ {
builder = new WebHostBuilder() builder = new WebHostBuilder()
.ConfigureServices(services =>
{
const string PairingToken = "TOKEN";
string paringToken = builder.GetSetting(PairingToken) ?? Environment.GetEnvironmentVariable($"ASPNETCORE_{PairingToken}");
services.AddSingleton<IStartupFilter>(
new IISSetupFilter(paringToken)
);
})
.UseConfiguration(config) .UseConfiguration(config)
.UseIISIntegration()
.UseStartup<Startup>(); .UseStartup<Startup>();
} }
@ -139,7 +146,7 @@ namespace AspnetCoreModule.TestSites.Standard
); );
try try
{ {
host.Run(); host.Run();
} }
catch catch
{ {

View File

@ -252,16 +252,16 @@ namespace AspnetCoreModule.TestSites.Standard
parameter = "1024"; parameter = "1024";
if (item.Length > action.Length) if (item.Length > action.Length)
{ {
parameter = item.Substring(action.Length); parameter = item.Substring(action.Length);
} }
long size = Convert.ToInt32(parameter); long size = Convert.ToInt32(parameter);
var rnd = new Random(); var rnd = new Random();
byte[] b = new byte[size*1024]; byte[] b = new byte[size * 1024];
b[rnd.Next(0, b.Length)] = byte.MaxValue; b[rnd.Next(0, b.Length)] = byte.MaxValue;
MemoryLeakList.Add(b); MemoryLeakList.Add(b);
response = "MemoryLeak, size:" + size.ToString() + " KB, total: " + MemoryLeakList.Count.ToString(); response = "MemoryLeak, size:" + size.ToString() + " KB, total: " + MemoryLeakList.Count.ToString();
} }
action = "ExpandEnvironmentVariables"; action = "ExpandEnvironmentVariables";
if (item.StartsWith(action)) if (item.StartsWith(action))
{ {
@ -269,7 +269,7 @@ namespace AspnetCoreModule.TestSites.Standard
{ {
parameter = item.Substring(action.Length); parameter = item.Substring(action.Length);
response = Environment.ExpandEnvironmentVariables("%" + parameter + "%"); response = Environment.ExpandEnvironmentVariables("%" + parameter + "%");
} }
} }
action = "GetEnvironmentVariables"; action = "GetEnvironmentVariables";
@ -285,9 +285,9 @@ namespace AspnetCoreModule.TestSites.Standard
response = String.Empty; response = String.Empty;
foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
{ {
response += de.Key + ":" + de.Value + "<br/>"; response += de.Key + ":" + de.Value + "<br/>";
} }
} }
action = "GetRequestHeaderValue"; action = "GetRequestHeaderValue";
@ -312,7 +312,7 @@ namespace AspnetCoreModule.TestSites.Standard
if (item.StartsWith(action)) if (item.StartsWith(action))
{ {
response = String.Empty; response = String.Empty;
foreach (var de in context.Request.Headers) foreach (var de in context.Request.Headers)
{ {
response += de.Key + ":" + de.Value + "<br/>"; response += de.Key + ":" + de.Value + "<br/>";
@ -326,7 +326,7 @@ namespace AspnetCoreModule.TestSites.Standard
if (item.Length > action.Length) if (item.Length > action.Length)
{ {
// this is the default response which is valid for chunked encoding // this is the default response which is valid for chunked encoding
response = "10\r\nManually Chunked\r\n0\r\n\r\n"; response = "10\r\nManually Chunked\r\n0\r\n\r\n";
parameter = item.Substring(action.Length); parameter = item.Substring(action.Length);
// valid encoding value: "chunked" or "chunked,gzip" // valid encoding value: "chunked" or "chunked,gzip"
@ -334,7 +334,7 @@ namespace AspnetCoreModule.TestSites.Standard
var tokens = parameter.Split("_"); var tokens = parameter.Split("_");
// if respons body value was also given after "_" delimeter, use the value as response data. // if respons body value was also given after "_" delimeter, use the value as response data.
if (tokens.Length == 2) if (tokens.Length == 2)
{ {
encoding = tokens[0]; encoding = tokens[0];
response = tokens[1]; response = tokens[1];
@ -344,20 +344,6 @@ namespace AspnetCoreModule.TestSites.Standard
} }
} }
} }
// Handle shutdown event from ANCM
if (HttpMethods.IsPost(context.Request.Method) &&
//context.Request.Path.Equals(ANCMRequestPath) &&
string.Equals("shutdown", context.Request.Headers["MS-ASPNETCORE-EVENT"], StringComparison.OrdinalIgnoreCase))
{
response = "shutdown";
string shutdownMode = Environment.GetEnvironmentVariable("GracefulShutdown");
if (String.IsNullOrEmpty(shutdownMode) || !shutdownMode.ToLower().StartsWith("disabled"))
{
context.Response.StatusCode = StatusCodes.Status202Accepted;
Program.AappLifetime.StopApplication();
}
}
return context.Response.WriteAsync(response); return context.Response.WriteAsync(response);
}); });
} }

View File

@ -0,0 +1,43 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Http;
using System;
using System.Security.Principal;
using System.Threading.Tasks;
namespace AspnetCoreModule.TestSites.Standard
{
public class TestMiddleWareBeforeIISMiddleWare
{
private readonly RequestDelegate next;
public TestMiddleWareBeforeIISMiddleWare(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
// if the given request is shutdown message from ANCM and the value of GracefulShutdown environment variable is set,
// the shutdown message is handled by this middleware instead of IISMiddleware.
if (HttpMethods.IsPost(context.Request.Method) &&
context.Request.Path.ToString().EndsWith("/iisintegration") &&
string.Equals("shutdown", context.Request.Headers["MS-ASPNETCORE-EVENT"], StringComparison.OrdinalIgnoreCase))
{
string shutdownMode = Environment.GetEnvironmentVariable("GracefulShutdown");
if (!string.IsNullOrWhiteSpace(shutdownMode) && shutdownMode.ToLower().StartsWith("disabled"))
{
//ignore shutdown Message returning 200 instead of 202 because the gracefulshutdown is disabled
context.Response.StatusCode = StatusCodes.Status200OK;
await context.Response.WriteAsync("Called ShutdownMessage with disabled of GracefulShutdown");
return;
}
}
await next.Invoke(context);
}
}
}