Skip to content

Instantly share code, notes, and snippets.

@poke
Created February 7, 2018 22:51
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save poke/665261ea1e4bcf233f9712ed5cb3c4f1 to your computer and use it in GitHub Desktop.
Save poke/665261ea1e4bcf233f9712ed5cb3c4f1 to your computer and use it in GitHub Desktop.
NanoKestrel: Running Kestrel in a console application with as minimum code as possible, i.e. avoiding all the WebHost stuff
using System;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace NanoKestrel
{
class Program
{
static async Task Main(string[] args)
{
var services = new ServiceCollection();
services.AddLogging(b =>
{
b.AddConsole();
b.AddFilter("Microsoft.AspNetCore.Server.Kestrel", LogLevel.Warning);
});
services.Configure<KestrelServerOptions>(options =>
{
options.Listen(IPAddress.Any, 8080);
});
services.AddSingleton<IServer, KestrelServer>();
services.AddSingleton<ITransportFactory, LibuvTransportFactory>();
services.AddSingleton<IApplicationLifetime, ApplicationLifetime>();
services.AddTransient<IHttpContextFactory, HttpContextFactory>();
services.AddTransient<HostingApplication>();
var serviceProvider = services.BuildServiceProvider();
var server = serviceProvider.GetRequiredService<IServer>();
var application = serviceProvider.GetRequiredService<HostingApplication>();
await server.StartAsync(application, default).ConfigureAwait(false);
Console.ReadLine();
}
}
public class HostingApplication : IHttpApplication<HttpContext>
{
private readonly ILogger<HostingApplication> _logger;
private readonly IHttpContextFactory _httpContextFactory;
public HostingApplication(ILogger<HostingApplication> logger, IHttpContextFactory httpContextFactory)
{
_logger = logger;
_httpContextFactory = httpContextFactory;
}
public HttpContext CreateContext(IFeatureCollection contextFeatures)
=> _httpContextFactory.Create(contextFeatures);
public void DisposeContext(HttpContext context, Exception exception)
=> _httpContextFactory.Dispose(context);
public async Task ProcessRequestAsync(HttpContext context)
{
_logger.LogInformation("{Method} {Path}", context.Request.Method, context.Request.Path);
if (context.Request.Path.StartsWithSegments("/hello"))
{
await context.Response.WriteAsync("Hello World!");
}
}
}
}
@CourseraSummerAssignments

LibuvTransportFactory is replaced by SocketTransportFactory and running this code makes the following error:
System.TypeLoadException: Could not load type 'Microsoft.Extensions.Primitives.InplaceStringBuilder' from assembly 'Microsoft.Extensions.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.

@vbond007
Copy link

Hi,
I used this code but replacing LibuvTransportFactory by SocketTransportFactory.
Everything works fine (the server is listening properly on the specified port number, a requestion is made and accepted) except when writing the reponse.
A NullReferenceException is thrown on context.Response.WriteAsync("Hello World!");

at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.CreateResponseHeader(Boolean appCompleted)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.InitializeResponseAsync(Int32 firstWriteByteCount)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.WriteAsync(ReadOnlyMemory`1 data, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response, String text, Encoding encoding, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response, String text, CancellationToken cancellationToken)

Any idea?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment