diff --git a/src/Kestrel/Kestrel.kproj b/src/Kestrel/Kestrel.kproj
index 0626b83124..219d40d100 100644
--- a/src/Kestrel/Kestrel.kproj
+++ b/src/Kestrel/Kestrel.kproj
@@ -25,6 +25,7 @@
2.0
+
diff --git a/src/Kestrel/Program.cs b/src/Kestrel/Program.cs
new file mode 100644
index 0000000000..7f877d9002
--- /dev/null
+++ b/src/Kestrel/Program.cs
@@ -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);
+ }
+ }
+}
+
diff --git a/src/Kestrel/ServerFactory.cs b/src/Kestrel/ServerFactory.cs
index a84ad1ae6e..c683d63be6 100644
--- a/src/Kestrel/ServerFactory.cs
+++ b/src/Kestrel/ServerFactory.cs
@@ -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
///
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();
var information = (ServerInformation)serverInformation;
- var engine = new KestrelEngine();
+ var engine = new KestrelEngine(_libraryManager);
engine.Start(1);
foreach (var address in information.Addresses)
{
diff --git a/src/Kestrel/project.json b/src/Kestrel/project.json
index 75592a1e20..2781b38bb3 100644
--- a/src/Kestrel/project.json
+++ b/src/Kestrel/project.json
@@ -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": {
diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/Listener.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/Listener.cs
index 123336ee6c..111df0065b 100644
--- a/src/Microsoft.AspNet.Server.Kestrel/Http/Listener.cs
+++ b/src/Microsoft.AspNet.Server.Kestrel/Http/Listener.cs
@@ -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);
}
diff --git a/src/Microsoft.AspNet.Server.Kestrel/KestrelEngine.cs b/src/Microsoft.AspNet.Server.Kestrel/KestrelEngine.cs
index 78abaa224e..257c127f6a 100644
--- a/src/Microsoft.AspNet.Server.Kestrel/KestrelEngine.cs
+++ b/src/Microsoft.AspNet.Server.Kestrel/KestrelEngine.cs
@@ -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();
Listeners = new List();
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; }
diff --git a/src/Microsoft.AspNet.Server.Kestrel/Microsoft.AspNet.Server.Kestrel.kproj b/src/Microsoft.AspNet.Server.Kestrel/Microsoft.AspNet.Server.Kestrel.kproj
index 943ae5c366..f860285346 100644
--- a/src/Microsoft.AspNet.Server.Kestrel/Microsoft.AspNet.Server.Kestrel.kproj
+++ b/src/Microsoft.AspNet.Server.Kestrel/Microsoft.AspNet.Server.Kestrel.kproj
@@ -23,7 +23,9 @@
2.0
+
+
diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs
index 7f4bf0eaf0..b326d101ad 100644
--- a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs
+++ b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs
@@ -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
diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/UvTcpHandle.cs b/src/Microsoft.AspNet.Server.Kestrel/Networking/UvTcpHandle.cs
index 0962ff650c..187656647f 100644
--- a/src/Microsoft.AspNet.Server.Kestrel/Networking/UvTcpHandle.cs
+++ b/src/Microsoft.AspNet.Server.Kestrel/Networking/UvTcpHandle.cs
@@ -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);
}
}
diff --git a/src/Microsoft.AspNet.Server.Kestrel/amd64/libuv.dll b/src/Microsoft.AspNet.Server.Kestrel/amd64/libuv.dll
new file mode 100644
index 0000000000..436ee491a1
Binary files /dev/null and b/src/Microsoft.AspNet.Server.Kestrel/amd64/libuv.dll differ
diff --git a/src/Microsoft.AspNet.Server.Kestrel/project.json b/src/Microsoft.AspNet.Server.Kestrel/project.json
index c20f6afdc4..3435c86826 100644
--- a/src/Microsoft.AspNet.Server.Kestrel/project.json
+++ b/src/Microsoft.AspNet.Server.Kestrel/project.json
@@ -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"
}
}
},
diff --git a/src/SampleApp/libuv.dll b/src/Microsoft.AspNet.Server.Kestrel/x86/libuv.dll
similarity index 100%
rename from src/SampleApp/libuv.dll
rename to src/Microsoft.AspNet.Server.Kestrel/x86/libuv.dll
diff --git a/src/SampleApp/Microsoft.AspNet.Hosting.ini b/src/SampleApp/Microsoft.AspNet.Hosting.ini
index f0def9d26b..3992612903 100644
--- a/src/SampleApp/Microsoft.AspNet.Hosting.ini
+++ b/src/SampleApp/Microsoft.AspNet.Hosting.ini
@@ -1,4 +1,3 @@
-Server=Kestrel
-; Server = Microsoft.AspNet.Server.WebListener
+Server = Microsoft.AspNet.Server.WebListener
Server.Urls = http://localhost:5000/
diff --git a/src/SampleApp/SampleApp.kproj b/src/SampleApp/SampleApp.kproj
index 35a172e4e1..a49005a910 100644
--- a/src/SampleApp/SampleApp.kproj
+++ b/src/SampleApp/SampleApp.kproj
@@ -25,14 +25,14 @@
2.0
- web
+
+
-
diff --git a/src/SampleApp/Startup.cs b/src/SampleApp/Startup.cs
index acafabf447..9eba33a386 100644
--- a/src/SampleApp/Startup.cs
+++ b/src/SampleApp/Startup.cs
@@ -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");
});
diff --git a/src/SampleApp/project.json b/src/SampleApp/project.json
index 12bc80da47..19174804d7 100644
--- a/src/SampleApp/project.json
+++ b/src/SampleApp/project.json
@@ -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"
}
}
diff --git a/test/Microsoft.AspNet.Server.KestralTests/EngineTests.cs b/test/Microsoft.AspNet.Server.KestralTests/EngineTests.cs
index e92e2a9b70..8873de5041 100644
--- a/test/Microsoft.AspNet.Server.KestralTests/EngineTests.cs
+++ b/test/Microsoft.AspNet.Server.KestralTests/EngineTests.cs
@@ -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);
diff --git a/test/Microsoft.AspNet.Server.KestralTests/Microsoft.AspNet.Server.KestralTests.kproj b/test/Microsoft.AspNet.Server.KestralTests/Microsoft.AspNet.Server.KestralTests.kproj
index aecd9b6963..78011f5326 100644
--- a/test/Microsoft.AspNet.Server.KestralTests/Microsoft.AspNet.Server.KestralTests.kproj
+++ b/test/Microsoft.AspNet.Server.KestralTests/Microsoft.AspNet.Server.KestralTests.kproj
@@ -24,7 +24,6 @@
-
diff --git a/test/Microsoft.AspNet.Server.KestralTests/NetworkingTests.cs b/test/Microsoft.AspNet.Server.KestralTests/NetworkingTests.cs
index 90860a6a8b..f2994a1e85 100644
--- a/test/Microsoft.AspNet.Server.KestralTests/NetworkingTests.cs
+++ b/test/Microsoft.AspNet.Server.KestralTests/NetworkingTests.cs
@@ -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]
diff --git a/test/Microsoft.AspNet.Server.KestralTests/TestServer.cs b/test/Microsoft.AspNet.Server.KestralTests/TestServer.cs
index 4f8a2dd440..e947f6b866 100644
--- a/test/Microsoft.AspNet.Server.KestralTests/TestServer.cs
+++ b/test/Microsoft.AspNet.Server.KestralTests/TestServer.cs
@@ -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 app)
{
- _engine = new KestrelEngine();
+ _engine = new KestrelEngine(LibraryManager);
_engine.Start(1);
_server = _engine.CreateServer(
"http",
"localhost",
54321,
app);
-
}
public void Dispose()
diff --git a/test/Microsoft.AspNet.Server.KestralTests/libuv.dll b/test/Microsoft.AspNet.Server.KestralTests/libuv.dll
deleted file mode 100644
index d3a5834718..0000000000
Binary files a/test/Microsoft.AspNet.Server.KestralTests/libuv.dll and /dev/null differ
diff --git a/test/Microsoft.AspNet.Server.KestralTests/project.json b/test/Microsoft.AspNet.Server.KestralTests/project.json
index 8cb87eaf48..c67b190301 100644
--- a/test/Microsoft.AspNet.Server.KestralTests/project.json
+++ b/test/Microsoft.AspNet.Server.KestralTests/project.json
@@ -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"
}
}