Adding "server.urls" configuration support to kestrel
This commit is contained in:
parent
6ac6419f4f
commit
17e566c5d1
|
|
@ -25,6 +25,7 @@
|
|||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ServerAddress.cs" />
|
||||
<Compile Include="ServerFactory.cs" />
|
||||
<Compile Include="ServerInformation.cs" />
|
||||
<Compile Include="ServerRequest.cs" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
namespace Kestrel
|
||||
{
|
||||
public class ServerAddress
|
||||
{
|
||||
public string Host { get; internal set; }
|
||||
public string Path { get; internal set; }
|
||||
public int Port { get; internal set; }
|
||||
public string Scheme { get; internal set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ using Microsoft.AspNet.Builder;
|
|||
using Microsoft.Framework.ConfigurationModel;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Server.Kestrel;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Kestrel
|
||||
{
|
||||
|
|
@ -21,15 +22,30 @@ namespace Kestrel
|
|||
|
||||
public IDisposable Start(IServerInformation serverInformation, Func<object, Task> application)
|
||||
{
|
||||
var disposables = new List<IDisposable>();
|
||||
var information = (ServerInformation)serverInformation;
|
||||
var engine = new KestrelEngine();
|
||||
engine.Start(1);
|
||||
engine.CreateServer(async frame =>
|
||||
foreach (var address in information.Addresses)
|
||||
{
|
||||
var request = new ServerRequest(frame);
|
||||
await application.Invoke(request);
|
||||
disposables.Add(engine.CreateServer(
|
||||
address.Scheme,
|
||||
address.Host,
|
||||
address.Port,
|
||||
async frame =>
|
||||
{
|
||||
var request = new ServerRequest(frame);
|
||||
await application.Invoke(request);
|
||||
}));
|
||||
}
|
||||
disposables.Add(engine);
|
||||
return new Disposable(() =>
|
||||
{
|
||||
foreach (var disposable in disposables)
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
});
|
||||
return engine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,43 @@
|
|||
using System;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.Framework.ConfigurationModel;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Kestrel
|
||||
{
|
||||
public class ServerInformation : IServerInformation
|
||||
{
|
||||
public ServerInformation()
|
||||
{
|
||||
Addresses = new List<ServerAddress>();
|
||||
}
|
||||
|
||||
public void Initialize(IConfiguration configuration)
|
||||
{
|
||||
string urls;
|
||||
if (!configuration.TryGet("server.urls", out urls))
|
||||
{
|
||||
urls = "http://+:5000/";
|
||||
}
|
||||
foreach (var url in urls.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
string scheme;
|
||||
string host;
|
||||
int port;
|
||||
string path;
|
||||
if (DeconstructUrl(url, out scheme, out host, out port, out path))
|
||||
{
|
||||
Addresses.Add(
|
||||
new ServerAddress
|
||||
{
|
||||
Scheme = scheme,
|
||||
Host = host,
|
||||
Port = port,
|
||||
Path = path
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
|
|
@ -17,5 +47,68 @@ namespace Kestrel
|
|||
return "Kestrel";
|
||||
}
|
||||
}
|
||||
|
||||
public IList<ServerAddress> Addresses { get; private set; }
|
||||
|
||||
internal static bool DeconstructUrl(
|
||||
string url,
|
||||
out string scheme,
|
||||
out string host,
|
||||
out int port,
|
||||
out string path)
|
||||
{
|
||||
url = url ?? string.Empty;
|
||||
|
||||
int delimiterStart1 = url.IndexOf("://", StringComparison.Ordinal);
|
||||
if (delimiterStart1 < 0)
|
||||
{
|
||||
scheme = null;
|
||||
host = null;
|
||||
port = 0;
|
||||
path = null;
|
||||
return false;
|
||||
}
|
||||
int delimiterEnd1 = delimiterStart1 + "://".Length;
|
||||
|
||||
int delimiterStart3 = url.IndexOf("/", delimiterEnd1, StringComparison.Ordinal);
|
||||
if (delimiterStart3 < 0)
|
||||
{
|
||||
delimiterStart3 = url.Length;
|
||||
}
|
||||
int delimiterStart2 = url.LastIndexOf(":", delimiterStart3 - 1, delimiterStart3 - delimiterEnd1, StringComparison.Ordinal);
|
||||
int delimiterEnd2 = delimiterStart2 + ":".Length;
|
||||
if (delimiterStart2 < 0)
|
||||
{
|
||||
delimiterStart2 = delimiterStart3;
|
||||
delimiterEnd2 = delimiterStart3;
|
||||
}
|
||||
|
||||
scheme = url.Substring(0, delimiterStart1);
|
||||
string portString = url.Substring(delimiterEnd2, delimiterStart3 - delimiterEnd2);
|
||||
int portNumber;
|
||||
if (int.TryParse(portString, NumberStyles.Integer, CultureInfo.InvariantCulture, out portNumber))
|
||||
{
|
||||
host = url.Substring(delimiterEnd1, delimiterStart2 - delimiterEnd1);
|
||||
port = portNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.Equals(scheme, "http", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
port = 80;
|
||||
}
|
||||
else if (string.Equals(scheme, "https", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
port = 443;
|
||||
}
|
||||
else
|
||||
{
|
||||
port = 0;
|
||||
}
|
||||
host = url.Substring(delimiterEnd1, delimiterStart3 - delimiterEnd1);
|
||||
}
|
||||
path = url.Substring(delimiterStart3);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
WriteAsync(buffer, offset, count).Wait();
|
||||
}
|
||||
|
||||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
|
|
|
|||
|
|
@ -45,33 +45,35 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
|||
Memory = memory;
|
||||
}
|
||||
|
||||
public Task StartAsync(KestrelThread thread, Func<Frame, Task> application)
|
||||
public Task StartAsync(
|
||||
string scheme,
|
||||
string host,
|
||||
int port,
|
||||
KestrelThread thread,
|
||||
Func<Frame, Task> application)
|
||||
{
|
||||
Thread = thread;
|
||||
Application = application;
|
||||
|
||||
var tcs = new TaskCompletionSource<int>();
|
||||
Thread.Post(OnStart, tcs);
|
||||
Thread.Post(_ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
ListenSocket = new UvTcpHandle();
|
||||
ListenSocket.Init(Thread.Loop);
|
||||
ListenSocket.Bind(new IPEndPoint(IPAddress.Any, port));
|
||||
ListenSocket.Listen(10, _connectionCallback, this);
|
||||
tcs.SetResult(0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcs.SetException(ex);
|
||||
}
|
||||
}, null);
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
public void OnStart(object parameter)
|
||||
{
|
||||
var tcs = (TaskCompletionSource<int>)parameter;
|
||||
try
|
||||
{
|
||||
ListenSocket = new UvTcpHandle();
|
||||
ListenSocket.Init(Thread.Loop);
|
||||
ListenSocket.Bind(new IPEndPoint(IPAddress.Any, 4001));
|
||||
ListenSocket.Listen(10, _connectionCallback, this);
|
||||
tcs.SetResult(0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcs.SetException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnConnection(UvStreamHandle listenSocket, int status)
|
||||
{
|
||||
var acceptSocket = new UvTcpHandle();
|
||||
|
|
|
|||
|
|
@ -48,13 +48,13 @@ namespace Microsoft.AspNet.Server.Kestrel
|
|||
Threads.Clear();
|
||||
}
|
||||
|
||||
public IDisposable CreateServer(Func<Frame, Task> application)
|
||||
public IDisposable CreateServer(string scheme, string host, int port, Func<Frame, Task> application)
|
||||
{
|
||||
var listeners = new List<Listener>();
|
||||
foreach (var thread in Threads)
|
||||
{
|
||||
var listener = new Listener(Memory);
|
||||
listener.StartAsync(thread, application).Wait();
|
||||
listener.StartAsync(scheme, host, port, thread, application).Wait();
|
||||
listeners.Add(listener);
|
||||
}
|
||||
return new Disposable(() =>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
Server=Kestrel
|
||||
; Server = Microsoft.AspNet.Server.WebListener
|
||||
Server.Urls = http://localhost:5000/
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="libuv.dll" />
|
||||
<Content Include="Microsoft.AspNet.Hosting.ini" />
|
||||
<Content Include="project.json" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Kestrel": "0.1-alpha-*"
|
||||
"Kestrel": "0.1-alpha-*",
|
||||
"Microsoft.AspNet.Server.WebListener": "0.1-alpha-*"
|
||||
},
|
||||
"configurations": {
|
||||
"net45": { },
|
||||
|
|
@ -11,6 +12,7 @@
|
|||
}
|
||||
},
|
||||
"commands": {
|
||||
"web": "Microsoft.AspNet.Hosting --server kestrel"
|
||||
"run": "Microsoft.AspNet.Hosting",
|
||||
"web": "Microsoft.AspNet.Hosting"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ namespace Microsoft.AspNet.Server.KestralTests
|
|||
{
|
||||
var engine = new KestrelEngine();
|
||||
engine.Start(1);
|
||||
var started = engine.CreateServer(App);
|
||||
var started = engine.CreateServer("http", "localhost", 54321, App);
|
||||
started.Dispose();
|
||||
engine.Dispose();
|
||||
}
|
||||
|
|
@ -70,10 +70,10 @@ namespace Microsoft.AspNet.Server.KestralTests
|
|||
{
|
||||
var engine = new KestrelEngine();
|
||||
engine.Start(1);
|
||||
var started = engine.CreateServer(App);
|
||||
var started = engine.CreateServer("http", "localhost", 54321, App);
|
||||
|
||||
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
socket.Connect(new IPEndPoint(IPAddress.Loopback, 4001));
|
||||
socket.Connect(new IPEndPoint(IPAddress.Loopback, 54321));
|
||||
socket.Send(Encoding.ASCII.GetBytes("POST / HTTP/1.0\r\n\r\nHello World"));
|
||||
socket.Shutdown(SocketShutdown.Send);
|
||||
var buffer = new byte[8192];
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Server.KestralTests
|
|||
public void Create()
|
||||
{
|
||||
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
_socket.Connect(new IPEndPoint(IPAddress.Loopback, 4001));
|
||||
_socket.Connect(new IPEndPoint(IPAddress.Loopback, 54321));
|
||||
|
||||
_stream = new NetworkStream(_socket, false);
|
||||
_reader = new StreamReader(_stream, Encoding.ASCII);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,11 @@ namespace Microsoft.AspNet.Server.KestralTests
|
|||
{
|
||||
_engine = new KestrelEngine();
|
||||
_engine.Start(1);
|
||||
_server = _engine.CreateServer(app);
|
||||
_server = _engine.CreateServer(
|
||||
"http",
|
||||
"localhost",
|
||||
54321,
|
||||
app);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue