Merge branch 'Daniel15/unix-sockets' into dev
This commit is contained in:
commit
ca0a42a01e
|
|
@ -13,6 +13,7 @@
|
||||||
},
|
},
|
||||||
"commands": {
|
"commands": {
|
||||||
"run": "Microsoft.AspNet.Server.Kestrel",
|
"run": "Microsoft.AspNet.Server.Kestrel",
|
||||||
|
"run-socket": "Microsoft.AspNet.Server.Kestrel --server.urls unix:///tmp/kestrel-test.sock",
|
||||||
"kestrel": "Microsoft.AspNet.Server.Kestrel",
|
"kestrel": "Microsoft.AspNet.Server.Kestrel",
|
||||||
"web": "Microsoft.AspNet.Hosting"
|
"web": "Microsoft.AspNet.Hosting"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright (c) .NET Foundation. 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.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A listener waits for incoming connections on a specified socket.
|
||||||
|
/// </summary>
|
||||||
|
public interface IListener : IDisposable
|
||||||
|
{
|
||||||
|
Task StartAsync(
|
||||||
|
string scheme,
|
||||||
|
string host,
|
||||||
|
int port,
|
||||||
|
KestrelThread thread,
|
||||||
|
Func<Frame, Task> application);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright (c) .NET Foundation. 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.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A primary listener waits for incoming connections on a specified socket. Incoming
|
||||||
|
/// connections may be passed to a secondary listener to handle.
|
||||||
|
/// </summary>
|
||||||
|
public interface IListenerPrimary : IListener
|
||||||
|
{
|
||||||
|
Task StartAsync(
|
||||||
|
string pipeName,
|
||||||
|
string scheme,
|
||||||
|
string host,
|
||||||
|
int port,
|
||||||
|
KestrelThread thread,
|
||||||
|
Func<Frame, Task> application);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright (c) .NET Foundation. 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.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A secondary listener is delegated requests from a primary listener via a named pipe or
|
||||||
|
/// UNIX domain socket.
|
||||||
|
/// </summary>
|
||||||
|
public interface IListenerSecondary : IDisposable
|
||||||
|
{
|
||||||
|
Task StartAsync(
|
||||||
|
string pipeName,
|
||||||
|
KestrelThread thread,
|
||||||
|
Func<Frame, Task> application);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,25 +1,22 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. 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.Infrastructure;
|
|
||||||
using Microsoft.AspNet.Server.Kestrel.Networking;
|
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Net;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel.Http
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Summary description for Accept
|
/// Base class for listeners in Kestrel. Listens for incoming connections
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Listener : ListenerContext, IDisposable
|
/// <typeparam name="T">Type of socket used by this listener</typeparam>
|
||||||
|
public abstract class Listener<T> : ListenerContext, IListener where T : UvStreamHandle
|
||||||
{
|
{
|
||||||
private static readonly Action<UvStreamHandle, int, Exception, object> _connectionCallback = ConnectionCallback;
|
protected T ListenSocket { get; private set; }
|
||||||
|
|
||||||
UvTcpHandle ListenSocket { get; set; }
|
protected static void ConnectionCallback(UvStreamHandle stream, int status, Exception error, object state)
|
||||||
|
|
||||||
private static void ConnectionCallback(UvStreamHandle stream, int status, Exception error, object state)
|
|
||||||
{
|
{
|
||||||
if (error != null)
|
if (error != null)
|
||||||
{
|
{
|
||||||
|
|
@ -27,11 +24,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
((Listener)state).OnConnection(stream, status);
|
((Listener<T>)state).OnConnection((T)stream, status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Listener(IMemoryPool memory)
|
protected Listener(IMemoryPool memory)
|
||||||
{
|
{
|
||||||
Memory = memory;
|
Memory = memory;
|
||||||
}
|
}
|
||||||
|
|
@ -51,10 +48,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ListenSocket = new UvTcpHandle();
|
ListenSocket = CreateListenSocket(host, port);
|
||||||
ListenSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
|
|
||||||
ListenSocket.Bind(new IPEndPoint(IPAddress.Any, port));
|
|
||||||
ListenSocket.Listen(Constants.ListenBacklog, _connectionCallback, this);
|
|
||||||
tcs.SetResult(0);
|
tcs.SetResult(0);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -65,16 +59,19 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
return tcs.Task;
|
return tcs.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnConnection(UvStreamHandle listenSocket, int status)
|
/// <summary>
|
||||||
{
|
/// Creates the socket used to listen for incoming connections
|
||||||
var acceptSocket = new UvTcpHandle();
|
/// </summary>
|
||||||
acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
|
protected abstract T CreateListenSocket(string host, int port);
|
||||||
listenSocket.Accept(acceptSocket);
|
|
||||||
|
|
||||||
DispatchConnection(acceptSocket);
|
/// <summary>
|
||||||
}
|
/// Handles an incoming connection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="listenSocket">Socket being used to listen on</param>
|
||||||
|
/// <param name="status">Connection status</param>
|
||||||
|
protected abstract void OnConnection(T listenSocket, int status);
|
||||||
|
|
||||||
protected virtual void DispatchConnection(UvTcpHandle socket)
|
protected virtual void DispatchConnection(T socket)
|
||||||
{
|
{
|
||||||
var connection = new Connection(this, socket);
|
var connection = new Connection(this, socket);
|
||||||
connection.Start();
|
connection.Start();
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,11 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel.Http
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
public class ListenerPrimary : Listener
|
/// <summary>
|
||||||
|
/// A primary listener waits for incoming connections on a specified socket. Incoming
|
||||||
|
/// connections may be passed to a secondary listener to handle.
|
||||||
|
/// </summary>
|
||||||
|
abstract public class ListenerPrimary<T> : Listener<T>, IListenerPrimary where T : UvStreamHandle
|
||||||
{
|
{
|
||||||
UvPipeHandle ListenPipe { get; set; }
|
UvPipeHandle ListenPipe { get; set; }
|
||||||
|
|
||||||
|
|
@ -17,7 +21,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
int _dispatchIndex;
|
int _dispatchIndex;
|
||||||
ArraySegment<ArraySegment<byte>> _1234 = new ArraySegment<ArraySegment<byte>>(new[] { new ArraySegment<byte>(new byte[] { 1, 2, 3, 4 }) });
|
ArraySegment<ArraySegment<byte>> _1234 = new ArraySegment<ArraySegment<byte>>(new[] { new ArraySegment<byte>(new byte[] { 1, 2, 3, 4 }) });
|
||||||
|
|
||||||
public ListenerPrimary(IMemoryPool memory) : base(memory)
|
protected ListenerPrimary(IMemoryPool memory) : base(memory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,7 +65,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
_dispatchPipes.Add(dispatchPipe);
|
_dispatchPipes.Add(dispatchPipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DispatchConnection(UvTcpHandle socket)
|
protected override void DispatchConnection(T socket)
|
||||||
{
|
{
|
||||||
var index = _dispatchIndex++ % (_dispatchPipes.Count + 1);
|
var index = _dispatchIndex++ % (_dispatchPipes.Count + 1);
|
||||||
if (index == _dispatchPipes.Count)
|
if (index == _dispatchPipes.Count)
|
||||||
|
|
@ -80,7 +84,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
(write2, status, error, state) =>
|
(write2, status, error, state) =>
|
||||||
{
|
{
|
||||||
write2.Dispose();
|
write2.Dispose();
|
||||||
((UvTcpHandle)state).Dispose();
|
((T)state).Dispose();
|
||||||
},
|
},
|
||||||
socket);
|
socket);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,15 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel.Http
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
public class ListenerSecondary : ListenerContext, IDisposable
|
/// <summary>
|
||||||
|
/// A secondary listener is delegated requests from a primary listener via a named pipe or
|
||||||
|
/// UNIX domain socket.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ListenerSecondary<T> : ListenerContext, IListenerSecondary where T : UvStreamHandle
|
||||||
{
|
{
|
||||||
UvPipeHandle DispatchPipe { get; set; }
|
UvPipeHandle DispatchPipe { get; set; }
|
||||||
|
|
||||||
public ListenerSecondary(IMemoryPool memory)
|
protected ListenerSecondary(IMemoryPool memory)
|
||||||
{
|
{
|
||||||
Memory = memory;
|
Memory = memory;
|
||||||
}
|
}
|
||||||
|
|
@ -64,8 +68,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var acceptSocket = new UvTcpHandle();
|
var acceptSocket = CreateAcceptSocket();
|
||||||
acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -102,6 +105,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
return tcs.Task;
|
return tcs.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a socket which can be used to accept an incoming connection
|
||||||
|
/// </summary>
|
||||||
|
protected abstract T CreateAcceptSocket();
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// Ensure the event loop is still running.
|
// Ensure the event loop is still running.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright (c) .NET Foundation. 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.Infrastructure;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Implementation of <see cref="Listener{T}"/> that uses UNIX domain sockets as its transport.
|
||||||
|
/// </summary>
|
||||||
|
public class PipeListener : Listener<UvPipeHandle>
|
||||||
|
{
|
||||||
|
public PipeListener(IMemoryPool memory) : base(memory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the socket used to listen for incoming connections
|
||||||
|
/// </summary>
|
||||||
|
protected override UvPipeHandle CreateListenSocket(string host, int port)
|
||||||
|
{
|
||||||
|
var socket = new UvPipeHandle();
|
||||||
|
socket.Init(Thread.Loop, false);
|
||||||
|
socket.Bind(host);
|
||||||
|
socket.Listen(Constants.ListenBacklog, ConnectionCallback, this);
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles an incoming connection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="listenSocket">Socket being used to listen on</param>
|
||||||
|
/// <param name="status">Connection status</param>
|
||||||
|
protected override void OnConnection(UvPipeHandle listenSocket, int status)
|
||||||
|
{
|
||||||
|
var acceptSocket = new UvPipeHandle();
|
||||||
|
acceptSocket.Init(Thread.Loop, false);
|
||||||
|
listenSocket.Accept(acceptSocket);
|
||||||
|
|
||||||
|
DispatchConnection(acceptSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright (c) .NET Foundation. 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.Infrastructure;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An implementation of <see cref="ListenerPrimary{T}"/> using UNIX sockets.
|
||||||
|
/// </summary>
|
||||||
|
public class PipeListenerPrimary : ListenerPrimary<UvPipeHandle>
|
||||||
|
{
|
||||||
|
public PipeListenerPrimary(IMemoryPool memory) : base(memory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the socket used to listen for incoming connections
|
||||||
|
/// </summary>
|
||||||
|
protected override UvPipeHandle CreateListenSocket(string host, int port)
|
||||||
|
{
|
||||||
|
var socket = new UvPipeHandle();
|
||||||
|
socket.Init(Thread.Loop, false);
|
||||||
|
socket.Bind(host);
|
||||||
|
socket.Listen(Constants.ListenBacklog, ConnectionCallback, this);
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles an incoming connection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="listenSocket">Socket being used to listen on</param>
|
||||||
|
/// <param name="status">Connection status</param>
|
||||||
|
protected override void OnConnection(UvPipeHandle listenSocket, int status)
|
||||||
|
{
|
||||||
|
var acceptSocket = new UvPipeHandle();
|
||||||
|
acceptSocket.Init(Thread.Loop, false);
|
||||||
|
listenSocket.Accept(acceptSocket);
|
||||||
|
|
||||||
|
DispatchConnection(acceptSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (c) .NET Foundation. 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.Networking;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An implementation of <see cref="ListenerSecondary{T}"/> using UNIX sockets.
|
||||||
|
/// </summary>
|
||||||
|
public class PipeListenerSecondary : ListenerSecondary<UvPipeHandle>
|
||||||
|
{
|
||||||
|
public PipeListenerSecondary(IMemoryPool memory) : base(memory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a socket which can be used to accept an incoming connection
|
||||||
|
/// </summary>
|
||||||
|
protected override UvPipeHandle CreateAcceptSocket()
|
||||||
|
{
|
||||||
|
var acceptSocket = new UvPipeHandle();
|
||||||
|
acceptSocket.Init(Thread.Loop, false);
|
||||||
|
return acceptSocket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Net;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Implementation of <see cref="Listener{T}"/> that uses TCP sockets as its transport.
|
||||||
|
/// </summary>
|
||||||
|
public class TcpListener : Listener<UvTcpHandle>
|
||||||
|
{
|
||||||
|
public TcpListener(IMemoryPool memory) : base(memory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the socket used to listen for incoming connections
|
||||||
|
/// </summary>
|
||||||
|
protected override UvTcpHandle CreateListenSocket(string host, int port)
|
||||||
|
{
|
||||||
|
var socket = new UvTcpHandle();
|
||||||
|
socket.Init(Thread.Loop, Thread.QueueCloseHandle);
|
||||||
|
socket.Bind(new IPEndPoint(IPAddress.Any, port));
|
||||||
|
socket.Listen(Constants.ListenBacklog, ConnectionCallback, this);
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle an incoming connection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="listenSocket">Socket being used to listen on</param>
|
||||||
|
/// <param name="status">Connection status</param>
|
||||||
|
protected override void OnConnection(UvTcpHandle listenSocket, int status)
|
||||||
|
{
|
||||||
|
var acceptSocket = new UvTcpHandle();
|
||||||
|
acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
|
||||||
|
listenSocket.Accept(acceptSocket);
|
||||||
|
|
||||||
|
DispatchConnection(acceptSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Net;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An implementation of <see cref="ListenerPrimary{T}"/> using TCP sockets.
|
||||||
|
/// </summary>
|
||||||
|
public class TcpListenerPrimary : ListenerPrimary<UvTcpHandle>
|
||||||
|
{
|
||||||
|
public TcpListenerPrimary(IMemoryPool memory) : base(memory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the socket used to listen for incoming connections
|
||||||
|
/// </summary>
|
||||||
|
protected override UvTcpHandle CreateListenSocket(string host, int port)
|
||||||
|
{
|
||||||
|
var socket = new UvTcpHandle();
|
||||||
|
socket.Init(Thread.Loop, Thread.QueueCloseHandle);
|
||||||
|
socket.Bind(new IPEndPoint(IPAddress.Any, port));
|
||||||
|
socket.Listen(Constants.ListenBacklog, ConnectionCallback, this);
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles an incoming connection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="listenSocket">Socket being used to listen on</param>
|
||||||
|
/// <param name="status">Connection status</param>
|
||||||
|
protected override void OnConnection(UvTcpHandle listenSocket, int status)
|
||||||
|
{
|
||||||
|
var acceptSocket = new UvTcpHandle();
|
||||||
|
acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
|
||||||
|
listenSocket.Accept(acceptSocket);
|
||||||
|
|
||||||
|
DispatchConnection(acceptSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (c) .NET Foundation. 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.Networking;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An implementation of <see cref="ListenerSecondary{T}"/> using TCP sockets.
|
||||||
|
/// </summary>
|
||||||
|
public class TcpListenerSecondary : ListenerSecondary<UvTcpHandle>
|
||||||
|
{
|
||||||
|
public TcpListenerSecondary(IMemoryPool memory) : base(memory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a socket which can be used to accept an incoming connection
|
||||||
|
/// </summary>
|
||||||
|
protected override UvTcpHandle CreateAcceptSocket()
|
||||||
|
{
|
||||||
|
var acceptSocket = new UvTcpHandle();
|
||||||
|
acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
|
||||||
|
return acceptSocket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
using System;
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
using System.Collections.Generic;
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
|
namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
|
||||||
{
|
{
|
||||||
internal class Constants
|
internal class Constants
|
||||||
{
|
{
|
||||||
public const int ListenBacklog = 128;
|
public const int ListenBacklog = 128;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// URL scheme for specifying Unix sockets in the configuration.
|
||||||
|
/// </summary>
|
||||||
|
public const string UnixScheme = "unix";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Http;
|
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Networking;
|
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||||
using Microsoft.Dnx.Runtime;
|
using Microsoft.Dnx.Runtime;
|
||||||
|
|
||||||
|
|
@ -69,7 +70,6 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
{
|
{
|
||||||
AppShutdown = appShutdownService;
|
AppShutdown = appShutdownService;
|
||||||
Threads = new List<KestrelThread>();
|
Threads = new List<KestrelThread>();
|
||||||
Listeners = new List<Listener>();
|
|
||||||
Memory = new MemoryPool();
|
Memory = new MemoryPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,7 +77,6 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
public IMemoryPool Memory { get; set; }
|
public IMemoryPool Memory { get; set; }
|
||||||
public IApplicationShutdown AppShutdown { get; private set; }
|
public IApplicationShutdown AppShutdown { get; private set; }
|
||||||
public List<KestrelThread> Threads { get; private set; }
|
public List<KestrelThread> Threads { get; private set; }
|
||||||
public List<Listener> Listeners { get; private set; }
|
|
||||||
|
|
||||||
public void Start(int count)
|
public void Start(int count)
|
||||||
{
|
{
|
||||||
|
|
@ -104,6 +103,7 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
public IDisposable CreateServer(string scheme, string host, int port, Func<Frame, Task> application)
|
public IDisposable CreateServer(string scheme, string host, int port, Func<Frame, Task> application)
|
||||||
{
|
{
|
||||||
var listeners = new List<IDisposable>();
|
var listeners = new List<IDisposable>();
|
||||||
|
var usingPipes = scheme == Constants.UnixScheme;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -116,19 +116,26 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
{
|
{
|
||||||
if (single)
|
if (single)
|
||||||
{
|
{
|
||||||
var listener = new Listener(Memory);
|
var listener = usingPipes ?
|
||||||
|
(IListener) new PipeListener(Memory) :
|
||||||
|
new TcpListener(Memory);
|
||||||
listeners.Add(listener);
|
listeners.Add(listener);
|
||||||
listener.StartAsync(scheme, host, port, thread, application).Wait();
|
listener.StartAsync(scheme, host, port, thread, application).Wait();
|
||||||
}
|
}
|
||||||
else if (first)
|
else if (first)
|
||||||
{
|
{
|
||||||
var listener = new ListenerPrimary(Memory);
|
var listener = usingPipes
|
||||||
|
? (IListenerPrimary) new PipeListenerPrimary(Memory)
|
||||||
|
: new TcpListenerPrimary(Memory);
|
||||||
|
|
||||||
listeners.Add(listener);
|
listeners.Add(listener);
|
||||||
listener.StartAsync(pipeName, scheme, host, port, thread, application).Wait();
|
listener.StartAsync(pipeName, scheme, host, port, thread, application).Wait();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var listener = new ListenerSecondary(Memory);
|
var listener = usingPipes
|
||||||
|
? (IListenerSecondary) new PipeListenerSecondary(Memory)
|
||||||
|
: new TcpListenerSecondary(Memory);
|
||||||
listeners.Add(listener);
|
listeners.Add(listener);
|
||||||
listener.StartAsync(pipeName, thread, application).Wait();
|
listener.StartAsync(pipeName, thread, application).Wait();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Hosting.Server;
|
using Microsoft.AspNet.Hosting.Server;
|
||||||
using Microsoft.AspNet.Http.Features;
|
using Microsoft.AspNet.Http.Features;
|
||||||
using Microsoft.AspNet.Server.Kestrel;
|
|
||||||
using Microsoft.Dnx.Runtime;
|
using Microsoft.Dnx.Runtime;
|
||||||
using Microsoft.Framework.Configuration;
|
using Microsoft.Framework.Configuration;
|
||||||
|
using Constants = Microsoft.AspNet.Server.Kestrel.Infrastructure.Constants;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel
|
namespace Microsoft.AspNet.Server.Kestrel
|
||||||
{
|
{
|
||||||
|
|
@ -43,7 +43,8 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
{
|
{
|
||||||
disposables.Add(engine.CreateServer(
|
disposables.Add(engine.CreateServer(
|
||||||
address.Scheme,
|
address.Scheme,
|
||||||
address.Host,
|
// Unix sockets use a file path, not a hostname.
|
||||||
|
address.Scheme == Constants.UnixScheme ? address.Path : address.Host,
|
||||||
address.Port,
|
address.Port,
|
||||||
async frame =>
|
async frame =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue