Adding amd64 support

Moves Libuv.dll into nupkg
Uses ILibraryManager to locate location for native libraries
Updates version numbers to 1.0.0-*
Throws exceptions with error text provided by libuv.dll
Bind to ip4 or ip6 endpoints
Getting server defaults from ini
Enabling "Kestrel" to be used as a Main entrypoint
This commit is contained in:
Louis DeJardin 2014-06-20 21:09:44 -07:00
parent 17e566c5d1
commit 9e4bc60205
22 changed files with 171 additions and 33 deletions

View File

@ -25,6 +25,7 @@
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="ServerAddress.cs" />
<Compile Include="ServerFactory.cs" />
<Compile Include="ServerInformation.cs" />

23
src/Kestrel/Program.cs Normal file
View File

@ -0,0 +1,23 @@
using System;
using System.Linq;
namespace Kestrel
{
public class Program
{
private readonly IServiceProvider _serviceProvider;
public Program(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void Main(string[] args)
{
var program = new Microsoft.AspNet.Hosting.Program(_serviceProvider);
var mergedArgs = new[] { "--server", "Kestrel" }.Concat(args).ToArray();
program.Main(mergedArgs);
}
}
}

View File

@ -5,6 +5,7 @@ using Microsoft.Framework.ConfigurationModel;
using System.Threading.Tasks;
using Microsoft.AspNet.Server.Kestrel;
using System.Collections.Generic;
using Microsoft.Framework.Runtime;
namespace Kestrel
{
@ -13,6 +14,13 @@ namespace Kestrel
/// </summary>
public class ServerFactory : IServerFactory
{
private readonly ILibraryManager _libraryManager;
public ServerFactory(ILibraryManager libraryManager)
{
_libraryManager = libraryManager;
}
public IServerInformation Initialize(IConfiguration configuration)
{
var information = new ServerInformation();
@ -24,7 +32,7 @@ namespace Kestrel
{
var disposables = new List<IDisposable>();
var information = (ServerInformation)serverInformation;
var engine = new KestrelEngine();
var engine = new KestrelEngine(_libraryManager);
engine.Start(1);
foreach (var address in information.Addresses)
{

View File

@ -1,8 +1,8 @@
{
"version": "0.1-alpha-*",
"version": "1.0.0-*",
"dependencies": {
"Microsoft.AspNet.Hosting": "0.1-*",
"Microsoft.AspNet.Server.Kestrel": "0.1-*"
"Microsoft.AspNet.Hosting": "1.0.0-*",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*"
},
"configurations": {
"net45": {

View File

@ -62,7 +62,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{
ListenSocket = new UvTcpHandle();
ListenSocket.Init(Thread.Loop);
ListenSocket.Bind(new IPEndPoint(IPAddress.Any, port));
ListenSocket.Bind(new IPEndPoint(IPAddress.IPv6Any, port));
ListenSocket.Listen(10, _connectionCallback, this);
tcs.SetResult(0);
}

View File

@ -6,19 +6,33 @@ using Microsoft.AspNet.Server.Kestrel.Networking;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.Framework.Runtime;
using System.IO;
namespace Microsoft.AspNet.Server.Kestrel
{
public class KestrelEngine : IDisposable
{
public KestrelEngine()
public KestrelEngine(ILibraryManager libraryManager)
{
Threads = new List<KestrelThread>();
Listeners = new List<Listener>();
Memory = new MemoryPool();
Libuv = new Libuv();
Libuv.Load("libuv.dll");
var library = libraryManager.GetLibraryInformation("Microsoft.AspNet.Server.Kestrel");
var libraryPath = library.Path;
if (library.Type == "Project")
{
libraryPath = Path.GetDirectoryName(libraryPath);
}
var architecture = IntPtr.Size == 4
? "x86"
: "amd64";
libraryPath = Path.Combine(libraryPath, architecture, "libuv.dll");
Libuv.Load(libraryPath);
}
public Libuv Libuv { get; private set; }

View File

@ -23,7 +23,9 @@
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Content Include="amd64\libuv.dll" />
<Content Include="project.json" />
<Content Include="x86\libuv.dll" />
</ItemGroup>
<ItemGroup>
<Compile Include="Http\FrameDuplexStream.cs" />

View File

@ -4,6 +4,7 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
namespace Microsoft.AspNet.Server.Kestrel.Networking
{
@ -37,10 +38,27 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
}
public int Check(int statusCode)
{
Exception error;
var result = Check(statusCode, out error);
if (error != null)
{
throw error;
}
return statusCode;
}
public int Check(int statusCode, out Exception error)
{
if (statusCode < 0)
{
throw new Exception("Status code " + statusCode);
var errorName = err_name(statusCode);
var errorDescription = strerror(statusCode);
error = new Exception("Error " + statusCode + " " + errorName + " " + errorDescription);
}
else
{
error = null;
}
return statusCode;
}
@ -234,6 +252,25 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
return _uv_handle_size(handleType);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate IntPtr uv_err_name(int err);
uv_err_name _uv_err_name;
public unsafe String err_name(int err)
{
IntPtr ptr = _uv_err_name(err);
return ptr == IntPtr.Zero ? null : Marshal.PtrToStringAnsi(ptr);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate IntPtr uv_strerror(int err);
uv_strerror _uv_strerror;
public unsafe String strerror(int err)
{
IntPtr ptr = _uv_strerror(err);
return ptr == IntPtr.Zero ? null : Marshal.PtrToStringAnsi(ptr);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int uv_req_size(int handleType);
uv_req_size _uv_req_size;
@ -246,18 +283,18 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
delegate int uv_ip4_addr(string ip, int port, out sockaddr addr);
uv_ip4_addr _uv_ip4_addr;
public void ip4_addr(string ip, int port, out sockaddr addr)
public int ip4_addr(string ip, int port, out sockaddr addr, out Exception error)
{
Check(_uv_ip4_addr(ip, port, out addr));
return Check(_uv_ip4_addr(ip, port, out addr), out error);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int uv_ip6_addr(string ip, int port, out sockaddr addr);
uv_ip6_addr _uv_ip6_addr;
public void ip6_addr(string ip, int port, out sockaddr addr)
public int ip6_addr(string ip, int port, out sockaddr addr, out Exception error)
{
Check(_uv_ip6_addr(ip, port, out addr));
return Check(_uv_ip6_addr(ip, port, out addr), out error);
}
public struct sockaddr

View File

@ -1,6 +1,7 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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.Net;
namespace Microsoft.AspNet.Server.Kestrel.Networking
@ -16,7 +17,21 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
public void Bind(IPEndPoint endpoint)
{
Libuv.sockaddr addr;
_uv.ip4_addr(endpoint.Address.ToString(), endpoint.Port, out addr);
var addressText = endpoint.Address.ToString();
Exception error1;
_uv.ip4_addr(addressText, endpoint.Port, out addr, out error1);
if (error1 != null)
{
Exception error2;
_uv.ip6_addr(addressText, endpoint.Port, out addr, out error2);
if (error2 != null)
{
throw error1;
}
}
_uv.tcp_bind(this, ref addr, 0);
}
}

Binary file not shown.

View File

@ -1,6 +1,7 @@
{
"version": "0.1-alpha-*",
"version": "1.0.0-*",
"dependencies": {
"Microsoft.Framework.Runtime.Interfaces": "1.0.0-*"
},
"configurations": {
"net45": { },
@ -19,7 +20,8 @@
"System.Net.Primitives": "4.0.10.0",
"System.Runtime.Extensions": "4.0.10.0",
"System.Threading": "4.0.0.0",
"System.Globalization": "4.0.10.0"
"System.Globalization": "4.0.10.0",
"System.Runtime.InteropServices": "4.0.20.0"
}
}
},

View File

@ -1,4 +1,3 @@

Server=Kestrel
; Server = Microsoft.AspNet.Server.WebListener
Server = Microsoft.AspNet.Server.WebListener
Server.Urls = http://localhost:5000/

View File

@ -25,14 +25,14 @@
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<CommandLineArguments>web</CommandLineArguments>
<CommandLineArguments>
</CommandLineArguments>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Startup.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="libuv.dll" />
<Content Include="Microsoft.AspNet.Hosting.ini" />
<Content Include="project.json" />
</ItemGroup>

View File

@ -15,6 +15,7 @@ namespace SampleApp
context.Request.Path,
context.Request.QueryString);
context.Response.ContentLength = 11;
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("Hello world");
});

View File

@ -1,7 +1,8 @@
{
"version": "1.0.0-*",
"dependencies": {
"Kestrel": "0.1-alpha-*",
"Microsoft.AspNet.Server.WebListener": "0.1-alpha-*"
"Kestrel": "1.0.0-*",
"Microsoft.AspNet.Server.WebListener": "1.0.0-*"
},
"configurations": {
"net45": { },
@ -12,7 +13,7 @@
}
},
"commands": {
"run": "Microsoft.AspNet.Hosting",
"run": "Kestrel",
"web": "Microsoft.AspNet.Hosting"
}
}

View File

@ -1,5 +1,7 @@
using Microsoft.AspNet.Server.Kestrel;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.Framework.Runtime;
using Microsoft.Framework.Runtime.Infrastructure;
using System;
using System.IO;
using System.Net;
@ -28,6 +30,17 @@ namespace Microsoft.AspNet.Server.KestralTests
await frame.ResponseBody.WriteAsync(buffer, 0, count);
}
}
ILibraryManager LibraryManager
{
get
{
var services = CallContextServiceLocator.Locator.ServiceProvider;
return (ILibraryManager)services.GetService(typeof(ILibraryManager));
}
}
private async Task AppChunked(Frame frame)
{
var data = new MemoryStream();
@ -49,7 +62,7 @@ namespace Microsoft.AspNet.Server.KestralTests
[Fact]
public async Task EngineCanStartAndStop()
{
var engine = new KestrelEngine();
var engine = new KestrelEngine(LibraryManager);
engine.Start(1);
engine.Dispose();
}
@ -57,7 +70,7 @@ namespace Microsoft.AspNet.Server.KestralTests
[Fact]
public async Task ListenerCanCreateAndDispose()
{
var engine = new KestrelEngine();
var engine = new KestrelEngine(LibraryManager);
engine.Start(1);
var started = engine.CreateServer("http", "localhost", 54321, App);
started.Dispose();
@ -68,7 +81,7 @@ namespace Microsoft.AspNet.Server.KestralTests
[Fact]
public async Task ConnectionCanReadAndWrite()
{
var engine = new KestrelEngine();
var engine = new KestrelEngine(LibraryManager);
engine.Start(1);
var started = engine.CreateServer("http", "localhost", 54321, App);

View File

@ -24,7 +24,6 @@
</PropertyGroup>
<ItemGroup>
<Content Include="project.json" />
<Content Include="libuv.dll" />
</ItemGroup>
<ItemGroup>
<Compile Include="EngineTests.cs" />

View File

@ -1,7 +1,10 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Server.Kestrel;
using Microsoft.AspNet.Server.Kestrel.Networking;
using Microsoft.Framework.Runtime;
using Microsoft.Framework.Runtime.Infrastructure;
using System;
using System.Net;
using System.Net.Sockets;
@ -19,8 +22,17 @@ namespace Microsoft.AspNet.Server.KestralTests
Libuv _uv;
public NetworkingTests()
{
_uv = new Libuv();
_uv.Load("libuv.dll");
var engine = new KestrelEngine(LibraryManager);
_uv = engine.Libuv;
}
ILibraryManager LibraryManager
{
get
{
var services = CallContextServiceLocator.Locator.ServiceProvider;
return (ILibraryManager)services.GetService(typeof(ILibraryManager));
}
}
[Fact]

View File

@ -1,5 +1,7 @@
using Microsoft.AspNet.Server.Kestrel;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.Framework.Runtime;
using Microsoft.Framework.Runtime.Infrastructure;
using System;
using System.Threading.Tasks;
@ -18,16 +20,24 @@ namespace Microsoft.AspNet.Server.KestralTests
Create(app);
}
ILibraryManager LibraryManager
{
get
{
var services = CallContextServiceLocator.Locator.ServiceProvider;
return (ILibraryManager)services.GetService(typeof(ILibraryManager));
}
}
public void Create(Func<Frame, Task> app)
{
_engine = new KestrelEngine();
_engine = new KestrelEngine(LibraryManager);
_engine.Start(1);
_server = _engine.CreateServer(
"http",
"localhost",
54321,
app);
}
public void Dispose()

View File

@ -1,10 +1,10 @@
{
"version": "0.1-alpha-*",
"version": "1.0.0-*",
"dependencies": {
"Xunit.KRunner": "0.1-*",
"Xunit.KRunner": "1.0.0-*",
"xunit.assert": "2.0.0-*",
"xunit.abstractions": "2.0.0-*",
"Microsoft.AspNet.Server.Kestrel": "0.1-*"
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*"
},
"configurations": {
"net45": {
@ -20,6 +20,7 @@
}
},
"commands": {
"run": "Xunit.KRunner",
"test": "Xunit.KRunner"
}
}