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

View File

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

View File

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

View File

@ -6,19 +6,33 @@ using Microsoft.AspNet.Server.Kestrel.Networking;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Server.Kestrel.Http; using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.Framework.Runtime;
using System.IO;
namespace Microsoft.AspNet.Server.Kestrel namespace Microsoft.AspNet.Server.Kestrel
{ {
public class KestrelEngine : IDisposable public class KestrelEngine : IDisposable
{ {
public KestrelEngine() public KestrelEngine(ILibraryManager libraryManager)
{ {
Threads = new List<KestrelThread>(); Threads = new List<KestrelThread>();
Listeners = new List<Listener>(); Listeners = new List<Listener>();
Memory = new MemoryPool(); Memory = new MemoryPool();
Libuv = new Libuv(); 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; } public Libuv Libuv { get; private set; }

View File

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

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text;
namespace Microsoft.AspNet.Server.Kestrel.Networking namespace Microsoft.AspNet.Server.Kestrel.Networking
{ {
@ -37,10 +38,27 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
} }
public int Check(int statusCode) 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) 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; return statusCode;
} }
@ -234,6 +252,25 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
return _uv_handle_size(handleType); 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)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int uv_req_size(int handleType); delegate int uv_req_size(int handleType);
uv_req_size _uv_req_size; 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); delegate int uv_ip4_addr(string ip, int port, out sockaddr addr);
uv_ip4_addr _uv_ip4_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)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int uv_ip6_addr(string ip, int port, out sockaddr addr); delegate int uv_ip6_addr(string ip, int port, out sockaddr addr);
uv_ip6_addr _uv_ip6_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 public struct sockaddr

View File

@ -1,6 +1,7 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Net; using System.Net;
namespace Microsoft.AspNet.Server.Kestrel.Networking namespace Microsoft.AspNet.Server.Kestrel.Networking
@ -16,7 +17,21 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
public void Bind(IPEndPoint endpoint) public void Bind(IPEndPoint endpoint)
{ {
Libuv.sockaddr addr; 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); _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": { "dependencies": {
"Microsoft.Framework.Runtime.Interfaces": "1.0.0-*"
}, },
"configurations": { "configurations": {
"net45": { }, "net45": { },
@ -19,7 +20,8 @@
"System.Net.Primitives": "4.0.10.0", "System.Net.Primitives": "4.0.10.0",
"System.Runtime.Extensions": "4.0.10.0", "System.Runtime.Extensions": "4.0.10.0",
"System.Threading": "4.0.0.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/ Server.Urls = http://localhost:5000/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,10 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // 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. // 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.AspNet.Server.Kestrel.Networking;
using Microsoft.Framework.Runtime;
using Microsoft.Framework.Runtime.Infrastructure;
using System; using System;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
@ -19,8 +22,17 @@ namespace Microsoft.AspNet.Server.KestralTests
Libuv _uv; Libuv _uv;
public NetworkingTests() public NetworkingTests()
{ {
_uv = new Libuv(); var engine = new KestrelEngine(LibraryManager);
_uv.Load("libuv.dll"); _uv = engine.Libuv;
}
ILibraryManager LibraryManager
{
get
{
var services = CallContextServiceLocator.Locator.ServiceProvider;
return (ILibraryManager)services.GetService(typeof(ILibraryManager));
}
} }
[Fact] [Fact]

View File

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

View File

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