Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Kestrel] Move to GenericHost #24279

Merged
13 commits merged into from
Aug 5, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{
Expand All @@ -33,22 +34,26 @@ public class InMemoryTransportBenchmark
private static readonly string _plaintextPipelinedExpectedResponse =
string.Concat(Enumerable.Repeat(_plaintextExpectedResponse, RequestParsingData.Pipelining));

private IWebHost _host;
private IHost _host;
private InMemoryConnection _connection;

[GlobalSetup(Target = nameof(Plaintext) + "," + nameof(PlaintextPipelined))]
public void GlobalSetupPlaintext()
{
var transportFactory = new InMemoryTransportFactory(connectionsPerEndPoint: 1);

_host = new WebHostBuilder()
// Prevent VS from attaching to hosting startup which could impact results
.UseSetting("preventHostingStartup", "true")
.UseKestrel()
// Bind to a single non-HTTPS endpoint
.UseUrls("http://127.0.0.1:5000")

_host = new HostBuilder()
.ConfigureWebHost(webHostBuilder =>
{
webHostBuilder
// Prevent VS from attaching to hosting startup which could impact results
.UseSetting("preventHostingStartup", "true")
.UseKestrel()
// Bind to a single non-HTTPS endpoint
.UseUrls("http://127.0.0.1:5000")
.Configure(app => app.UseMiddleware<PlaintextMiddleware>());
})
.ConfigureServices(services => services.AddSingleton<IConnectionListenerFactory>(transportFactory))
.Configure(app => app.UseMiddleware<PlaintextMiddleware>())
.Build();

_host.Start();
Expand Down
86 changes: 45 additions & 41 deletions src/Servers/Kestrel/samples/Http2SampleApp/Program.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System;
using System.IO;
using System.Net;
using System.Security.Authentication;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Connections.Features;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace Http2SampleApp
Expand All @@ -15,54 +15,58 @@ public class Program
{
public static void Main(string[] args)
{
var hostBuilder = new WebHostBuilder()
.ConfigureLogging((_, factory) =>
var hostBuilder = new HostBuilder()
.ConfigureWebHost(webHostBuilder =>
{
// Set logging to the MAX.
factory.SetMinimumLevel(LogLevel.Trace);
factory.AddConsole();
})
.UseKestrel()
.ConfigureKestrel((context, options) =>
{
var basePort = context.Configuration.GetValue<int?>("BASE_PORT") ?? 5000;

// Http/1.1 endpoint for comparison
options.ListenAnyIP(basePort, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1;
});

// TLS Http/1.1 or HTTP/2 endpoint negotiated via ALPN
options.ListenAnyIP(basePort + 1, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
listenOptions.UseHttps();
listenOptions.Use((context, next) =>
webHostBuilder
.UseKestrel()
.ConfigureKestrel((context, options) =>
{
// https://tools.ietf.org/html/rfc7540#appendix-A
// Allows filtering TLS handshakes on a per connection basis
var basePort = context.Configuration.GetValue<int?>("BASE_PORT") ?? 5000;

var tlsFeature = context.Features.Get<ITlsHandshakeFeature>();
// Http/1.1 endpoint for comparison
options.ListenAnyIP(basePort, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1;
});

if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
// TLS Http/1.1 or HTTP/2 endpoint negotiated via ALPN
options.ListenAnyIP(basePort + 1, listenOptions =>
{
throw new NotSupportedException("Prohibited cipher: " + tlsFeature.CipherAlgorithm);
}
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
listenOptions.UseHttps();
listenOptions.Use((context, next) =>
{
// https://tools.ietf.org/html/rfc7540#appendix-A
// Allows filtering TLS handshakes on a per connection basis

return next();
});
});
var tlsFeature = context.Features.Get<ITlsHandshakeFeature>();

// Prior knowledge, no TLS handshake. WARNING: Not supported by browsers
// but useful for the h2spec tests
options.ListenAnyIP(basePort + 5, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
{
throw new NotSupportedException("Prohibited cipher: " + tlsFeature.CipherAlgorithm);
}

return next();
});
});

// Prior knowledge, no TLS handshake. WARNING: Not supported by browsers
// but useful for the h2spec tests
options.ListenAnyIP(basePort + 5, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>();
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>();
.ConfigureLogging((_, factory) =>
{
// Set logging to the MAX.
factory.SetMinimumLevel(LogLevel.Trace);
factory.AddConsole();
});

hostBuilder.Build().Run();
}
Expand Down
17 changes: 11 additions & 6 deletions src/Servers/Kestrel/samples/LargeResponseApp/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace LargeResponseApp
{
Expand Down Expand Up @@ -38,13 +39,17 @@ public void Configure(IApplicationBuilder app)

public static Task Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel(options =>
var host = new HostBuilder()
.ConfigureWebHost(webHostBuilder =>
{
options.Listen(IPAddress.Loopback, 5001);
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
webHostBuilder
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, 5001);
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>();
})
.Build();

return host.RunAsync();
Expand Down
15 changes: 10 additions & 5 deletions src/Servers/Kestrel/samples/PlaintextApp/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace PlaintextApp
{
Expand All @@ -34,13 +35,17 @@ public void Configure(IApplicationBuilder app)

public static async Task Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel(options =>
var host = new HostBuilder()
.ConfigureWebHost(webHostBuilder =>
{
options.Listen(IPAddress.Loopback, 5001);
webHostBuilder
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, 5001);
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>();
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();

await host.RunAsync();
Expand Down
99 changes: 52 additions & 47 deletions src/Servers/Kestrel/samples/QuicSampleApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace QuicSampleApp
Expand All @@ -22,60 +23,64 @@ public void Configure(IApplicationBuilder app)

public static void Main(string[] args)
{
var hostBuilder = new WebHostBuilder()
.ConfigureLogging((_, factory) =>
{
factory.SetMinimumLevel(LogLevel.Debug);
factory.AddConsole();
})
.UseKestrel()
.UseQuic(options =>
{
options.Certificate = null;
options.Alpn = "QuicTest";
options.IdleTimeout = TimeSpan.FromHours(1);
})
.ConfigureKestrel((context, options) =>
{
var basePort = 5555;
var hostBuilder = new HostBuilder()
.ConfigureWebHost(webHostBuilder =>
{
webHostBuilder
.UseKestrel()
.UseQuic(options =>
{
options.Certificate = null;
options.Alpn = "QuicTest";
options.IdleTimeout = TimeSpan.FromHours(1);
})
.ConfigureKestrel((context, options) =>
{
var basePort = 5555;

options.Listen(IPAddress.Any, basePort, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http3;
options.Listen(IPAddress.Any, basePort, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http3;

async Task EchoServer(MultiplexedConnectionContext connection)
{
// For graceful shutdown
async Task EchoServer(MultiplexedConnectionContext connection)
{
// For graceful shutdown

while (true)
{
var stream = await connection.AcceptAsync();
while (true)
{
var result = await stream.Transport.Input.ReadAsync();
while (true)
{
var stream = await connection.AcceptAsync();
while (true)
{
var result = await stream.Transport.Input.ReadAsync();

if (result.IsCompleted)
{
break;
}
if (result.IsCompleted)
{
break;
}

await stream.Transport.Output.WriteAsync(result.Buffer.ToArray());
await stream.Transport.Output.WriteAsync(result.Buffer.ToArray());

stream.Transport.Input.AdvanceTo(result.Buffer.End);
}
}
}
stream.Transport.Input.AdvanceTo(result.Buffer.End);
}
}
}

((IMultiplexedConnectionBuilder)listenOptions).Use(next =>
{
return context =>
{
return EchoServer(context);
};
});
});
})
.UseStartup<Startup>();
((IMultiplexedConnectionBuilder)listenOptions).Use(next =>
{
return context =>
{
return EchoServer(context);
};
});
});
})
.UseStartup<Startup>();
})
.ConfigureLogging((_, factory) =>
{
factory.SetMinimumLevel(LogLevel.Debug);
factory.AddConsole();
});

hostBuilder.Build().Run();
}
Expand Down
Loading