Fixing a header parsing bug
When request header data arrives with \r\n split across packets
This commit is contained in:
parent
e5a3bda3a2
commit
52dc37eae7
|
|
@ -614,9 +614,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
chFirst = scan.Take(); // expecting: /r
|
chFirst = scan.Take(); // expecting: /r
|
||||||
chSecond = scan.Take(); // expecting: /n
|
chSecond = scan.Take(); // expecting: /n
|
||||||
|
|
||||||
if (chSecond == '\r')
|
if (chSecond != '\n')
|
||||||
{
|
{
|
||||||
// special case, "\r\r". move to the 2nd "\r" and try again
|
// "\r" was all by itself, move just after it and try again
|
||||||
scan = endValue;
|
scan = endValue;
|
||||||
scan.Take();
|
scan.Take();
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -633,6 +633,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = beginName.GetArraySegment(endName);
|
var name = beginName.GetArraySegment(endName);
|
||||||
|
#if DEBUG
|
||||||
|
var nameString = beginName.GetString(endName);
|
||||||
|
#endif
|
||||||
var value = beginValue.GetString(endValue);
|
var value = beginValue.GetString(endValue);
|
||||||
if (wrapping)
|
if (wrapping)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class Listener : ListenerContext, IDisposable
|
public abstract class Listener : ListenerContext, IDisposable
|
||||||
{
|
{
|
||||||
protected Listener(ServiceContext serviceContext) : base(serviceContext)
|
protected Listener(ServiceContext serviceContext)
|
||||||
|
: base(serviceContext)
|
||||||
{
|
{
|
||||||
Memory2 = new MemoryPool2();
|
Memory2 = new MemoryPool2();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,17 +7,19 @@ using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel.Http
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
public class ListenerContext
|
public class ListenerContext : ServiceContext
|
||||||
{
|
{
|
||||||
public ListenerContext() { }
|
public ListenerContext()
|
||||||
|
{
|
||||||
public ListenerContext(ServiceContext serviceContext)
|
}
|
||||||
|
|
||||||
|
public ListenerContext(ServiceContext serviceContext)
|
||||||
|
: base(serviceContext)
|
||||||
{
|
{
|
||||||
Memory = serviceContext.Memory;
|
|
||||||
Log = serviceContext.Log;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListenerContext(ListenerContext listenerContext)
|
public ListenerContext(ListenerContext listenerContext)
|
||||||
|
: base(listenerContext)
|
||||||
{
|
{
|
||||||
Thread = listenerContext.Thread;
|
Thread = listenerContext.Thread;
|
||||||
Application = listenerContext.Application;
|
Application = listenerContext.Application;
|
||||||
|
|
@ -30,10 +32,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
|
||||||
public Func<Frame, Task> Application { get; set; }
|
public Func<Frame, Task> Application { get; set; }
|
||||||
|
|
||||||
public IMemoryPool Memory { get; set; }
|
|
||||||
|
|
||||||
public MemoryPool2 Memory2 { get; set; }
|
public MemoryPool2 Memory2 { get; set; }
|
||||||
|
|
||||||
public IKestrelTrace Log { get; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,11 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
private ExceptionDispatchInfo _closeError;
|
private ExceptionDispatchInfo _closeError;
|
||||||
private IKestrelTrace _log;
|
private IKestrelTrace _log;
|
||||||
|
|
||||||
public KestrelThread(KestrelEngine engine, ServiceContext serviceContext)
|
public KestrelThread(KestrelEngine engine)
|
||||||
{
|
{
|
||||||
_engine = engine;
|
_engine = engine;
|
||||||
_appShutdown = serviceContext.AppShutdown;
|
_appShutdown = engine.AppShutdown;
|
||||||
_log = serviceContext.Log;
|
_log = engine.Log;
|
||||||
_loop = new UvLoopHandle(_log);
|
_loop = new UvLoopHandle(_log);
|
||||||
_post = new UvAsyncHandle(_log);
|
_post = new UvAsyncHandle(_log);
|
||||||
_thread = new Thread(ThreadStart);
|
_thread = new Thread(ThreadStart);
|
||||||
|
|
|
||||||
|
|
@ -12,87 +12,87 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class KestrelTrace : IKestrelTrace
|
public class KestrelTrace : IKestrelTrace
|
||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
protected readonly ILogger _logger;
|
||||||
|
|
||||||
public KestrelTrace(ILogger logger)
|
public KestrelTrace(ILogger logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionStart(long connectionId)
|
public virtual void ConnectionStart(long connectionId)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(1, @"Connection id ""{ConnectionId}"" started.", connectionId);
|
_logger.LogDebug(1, @"Connection id ""{ConnectionId}"" started.", connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionStop(long connectionId)
|
public virtual void ConnectionStop(long connectionId)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(2, @"Connection id ""{ConnectionId}"" stopped.", connectionId);
|
_logger.LogDebug(2, @"Connection id ""{ConnectionId}"" stopped.", connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionRead(long connectionId, int count)
|
public virtual void ConnectionRead(long connectionId, int count)
|
||||||
{
|
{
|
||||||
// Don't log for now since this could be *too* verbose.
|
// Don't log for now since this could be *too* verbose.
|
||||||
// Reserved: Event ID 3
|
// Reserved: Event ID 3
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionPause(long connectionId)
|
public virtual void ConnectionPause(long connectionId)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(4, @"Connection id ""{ConnectionId}"" paused.", connectionId);
|
_logger.LogDebug(4, @"Connection id ""{ConnectionId}"" paused.", connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionResume(long connectionId)
|
public virtual void ConnectionResume(long connectionId)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(5, @"Connection id ""{ConnectionId}"" resumed.", connectionId);
|
_logger.LogDebug(5, @"Connection id ""{ConnectionId}"" resumed.", connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionReadFin(long connectionId)
|
public virtual void ConnectionReadFin(long connectionId)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(6, @"Connection id ""{ConnectionId}"" received FIN.", connectionId);
|
_logger.LogDebug(6, @"Connection id ""{ConnectionId}"" received FIN.", connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionWriteFin(long connectionId)
|
public virtual void ConnectionWriteFin(long connectionId)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(7, @"Connection id ""{ConnectionId}"" sending FIN.", connectionId);
|
_logger.LogDebug(7, @"Connection id ""{ConnectionId}"" sending FIN.", connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionWroteFin(long connectionId, int status)
|
public virtual void ConnectionWroteFin(long connectionId, int status)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(8, @"Connection id ""{ConnectionId}"" sent FIN with status ""{Status}"".", connectionId, status);
|
_logger.LogDebug(8, @"Connection id ""{ConnectionId}"" sent FIN with status ""{Status}"".", connectionId, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionKeepAlive(long connectionId)
|
public virtual void ConnectionKeepAlive(long connectionId)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(9, @"Connection id ""{ConnectionId}"" completed keep alive response.", connectionId);
|
_logger.LogDebug(9, @"Connection id ""{ConnectionId}"" completed keep alive response.", connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionDisconnect(long connectionId)
|
public virtual void ConnectionDisconnect(long connectionId)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(10, @"Connection id ""{ConnectionId}"" disconnected.", connectionId);
|
_logger.LogDebug(10, @"Connection id ""{ConnectionId}"" disconnected.", connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionWrite(long connectionId, int count)
|
public virtual void ConnectionWrite(long connectionId, int count)
|
||||||
{
|
{
|
||||||
// Don't log for now since this could be *too* verbose.
|
// Don't log for now since this could be *too* verbose.
|
||||||
// Reserved: Event ID 11
|
// Reserved: Event ID 11
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectionWriteCallback(long connectionId, int status)
|
public virtual void ConnectionWriteCallback(long connectionId, int status)
|
||||||
{
|
{
|
||||||
// Don't log for now since this could be *too* verbose.
|
// Don't log for now since this could be *too* verbose.
|
||||||
// Reserved: Event ID 12
|
// Reserved: Event ID 12
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
|
public virtual void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
|
||||||
{
|
{
|
||||||
_logger.Log(logLevel, eventId, state, exception, formatter);
|
_logger.Log(logLevel, eventId, state, exception, formatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsEnabled(LogLevel logLevel)
|
public virtual bool IsEnabled(LogLevel logLevel)
|
||||||
{
|
{
|
||||||
return _logger.IsEnabled(logLevel);
|
return _logger.IsEnabled(logLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDisposable BeginScopeImpl(object state)
|
public virtual IDisposable BeginScopeImpl(object state)
|
||||||
{
|
{
|
||||||
return _logger.BeginScopeImpl(state);
|
return _logger.BeginScopeImpl(state);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,10 @@ using Microsoft.Framework.Logging;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel
|
namespace Microsoft.AspNet.Server.Kestrel
|
||||||
{
|
{
|
||||||
public class KestrelEngine : IDisposable
|
public class KestrelEngine : ServiceContext, IDisposable
|
||||||
{
|
{
|
||||||
private readonly ServiceContext _serviceContext;
|
public KestrelEngine(ILibraryManager libraryManager, ServiceContext context)
|
||||||
|
: this(context)
|
||||||
public KestrelEngine(ILibraryManager libraryManager, IApplicationShutdown appShutdownService, ILogger logger)
|
|
||||||
: this(appShutdownService, logger)
|
|
||||||
{
|
{
|
||||||
Libuv = new Libuv();
|
Libuv = new Libuv();
|
||||||
|
|
||||||
|
|
@ -63,21 +61,15 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
}
|
}
|
||||||
|
|
||||||
// For testing
|
// For testing
|
||||||
internal KestrelEngine(Libuv uv, IApplicationShutdown appShutdownService, ILogger logger)
|
internal KestrelEngine(Libuv uv, ServiceContext context)
|
||||||
: this(appShutdownService, logger)
|
: this(context)
|
||||||
{
|
{
|
||||||
Libuv = uv;
|
Libuv = uv;
|
||||||
}
|
}
|
||||||
|
|
||||||
private KestrelEngine(IApplicationShutdown appShutdownService, ILogger logger)
|
private KestrelEngine(ServiceContext context)
|
||||||
|
: base(context)
|
||||||
{
|
{
|
||||||
_serviceContext = new ServiceContext
|
|
||||||
{
|
|
||||||
AppShutdown = appShutdownService,
|
|
||||||
Memory = new MemoryPool(),
|
|
||||||
Log = new KestrelTrace(logger)
|
|
||||||
};
|
|
||||||
|
|
||||||
Threads = new List<KestrelThread>();
|
Threads = new List<KestrelThread>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,7 +80,7 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
{
|
{
|
||||||
for (var index = 0; index != count; ++index)
|
for (var index = 0; index != count; ++index)
|
||||||
{
|
{
|
||||||
Threads.Add(new KestrelThread(this, _serviceContext));
|
Threads.Add(new KestrelThread(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var thread in Threads)
|
foreach (var thread in Threads)
|
||||||
|
|
@ -128,16 +120,16 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
if (single)
|
if (single)
|
||||||
{
|
{
|
||||||
var listener = usingPipes ?
|
var listener = usingPipes ?
|
||||||
(Listener) new PipeListener(_serviceContext) :
|
(Listener) new PipeListener(this) :
|
||||||
new TcpListener(_serviceContext);
|
new TcpListener(this);
|
||||||
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 = usingPipes
|
var listener = usingPipes
|
||||||
? (ListenerPrimary) new PipeListenerPrimary(_serviceContext)
|
? (ListenerPrimary) new PipeListenerPrimary(this)
|
||||||
: new TcpListenerPrimary(_serviceContext);
|
: new TcpListenerPrimary(this);
|
||||||
|
|
||||||
listeners.Add(listener);
|
listeners.Add(listener);
|
||||||
listener.StartAsync(pipeName, scheme, host, port, thread, application).Wait();
|
listener.StartAsync(pipeName, scheme, host, port, thread, application).Wait();
|
||||||
|
|
@ -145,8 +137,8 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var listener = usingPipes
|
var listener = usingPipes
|
||||||
? (ListenerSecondary) new PipeListenerSecondary(_serviceContext)
|
? (ListenerSecondary) new PipeListenerSecondary(this)
|
||||||
: new TcpListenerSecondary(_serviceContext);
|
: new TcpListenerSecondary(this);
|
||||||
listeners.Add(listener);
|
listeners.Add(listener);
|
||||||
listener.StartAsync(pipeName, thread, application).Wait();
|
listener.StartAsync(pipeName, thread, application).Wait();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,14 +53,14 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var information = (KestrelServerInformation)serverFeatures.Get<IKestrelServerInformation>();
|
var information = (KestrelServerInformation)serverFeatures.Get<IKestrelServerInformation>();
|
||||||
var engine = new KestrelEngine(_libraryManager, _appShutdownService, _logger);
|
var engine = new KestrelEngine(_libraryManager, new ServiceContext { AppShutdown = _appShutdownService, Log = new KestrelTrace(_logger) });
|
||||||
|
|
||||||
disposables.Push(engine);
|
disposables.Push(engine);
|
||||||
|
|
||||||
if (information.ThreadCount < 0)
|
if (information.ThreadCount < 0)
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException(nameof(information.ThreadCount),
|
throw new ArgumentOutOfRangeException(nameof(information.ThreadCount),
|
||||||
information.ThreadCount,
|
information.ThreadCount,
|
||||||
"ThreadCount cannot be negative");
|
"ThreadCount cannot be negative");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,18 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
{
|
{
|
||||||
public class ServiceContext
|
public class ServiceContext
|
||||||
{
|
{
|
||||||
|
public ServiceContext()
|
||||||
|
{
|
||||||
|
Memory = new MemoryPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceContext(ServiceContext context)
|
||||||
|
{
|
||||||
|
AppShutdown = context.AppShutdown;
|
||||||
|
Memory = context.Memory;
|
||||||
|
Log = context.Log;
|
||||||
|
}
|
||||||
|
|
||||||
public IApplicationShutdown AppShutdown { get; set; }
|
public IApplicationShutdown AppShutdown { get; set; }
|
||||||
|
|
||||||
public IMemoryPool Memory { get; set; }
|
public IMemoryPool Memory { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -61,19 +61,20 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
|
|
||||||
private async Task AppChunked(Frame frame)
|
private async Task AppChunked(Frame frame)
|
||||||
{
|
{
|
||||||
|
Console.WriteLine($"----");
|
||||||
|
Console.WriteLine($"{frame.Method} {frame.RequestUri} {frame.HttpVersion}");
|
||||||
foreach (var h in frame.RequestHeaders)
|
foreach (var h in frame.RequestHeaders)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{h.Key}: {h.Value}");
|
Console.WriteLine($"{h.Key}: {h.Value}");
|
||||||
}
|
}
|
||||||
Console.WriteLine($"");
|
Console.WriteLine($"");
|
||||||
|
|
||||||
frame.ResponseHeaders.Clear();
|
|
||||||
var data = new MemoryStream();
|
var data = new MemoryStream();
|
||||||
while(true)
|
await frame.RequestBody.CopyToAsync(data);
|
||||||
{
|
|
||||||
await frame.RequestBody.CopyToAsync(data);
|
|
||||||
}
|
|
||||||
var bytes = data.ToArray();
|
var bytes = data.ToArray();
|
||||||
|
Console.WriteLine($"{Encoding.ASCII.GetString(bytes)}");
|
||||||
|
|
||||||
|
frame.ResponseHeaders.Clear();
|
||||||
frame.ResponseHeaders["Content-Length"] = new[] { bytes.Length.ToString() };
|
frame.ResponseHeaders["Content-Length"] = new[] { bytes.Length.ToString() };
|
||||||
await frame.ResponseBody.WriteAsync(bytes, 0, bytes.Length);
|
await frame.ResponseBody.WriteAsync(bytes, 0, bytes.Length);
|
||||||
}
|
}
|
||||||
|
|
@ -87,7 +88,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public void EngineCanStartAndStop()
|
public void EngineCanStartAndStop()
|
||||||
{
|
{
|
||||||
var engine = new KestrelEngine(LibraryManager, new ShutdownNotImplemented(), new TestLogger());
|
var engine = new KestrelEngine(LibraryManager, new TestServiceContext());
|
||||||
engine.Start(1);
|
engine.Start(1);
|
||||||
engine.Dispose();
|
engine.Dispose();
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +96,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ListenerCanCreateAndDispose()
|
public void ListenerCanCreateAndDispose()
|
||||||
{
|
{
|
||||||
var engine = new KestrelEngine(LibraryManager, new ShutdownNotImplemented(), new TestLogger());
|
var engine = new KestrelEngine(LibraryManager, new TestServiceContext());
|
||||||
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();
|
||||||
|
|
@ -106,7 +107,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ConnectionCanReadAndWrite()
|
public void ConnectionCanReadAndWrite()
|
||||||
{
|
{
|
||||||
var engine = new KestrelEngine(LibraryManager, new ShutdownNotImplemented(), new TestLogger());
|
var engine = new KestrelEngine(LibraryManager, new TestServiceContext());
|
||||||
engine.Start(1);
|
engine.Start(1);
|
||||||
var started = engine.CreateServer("http", "localhost", 54321, App);
|
var started = engine.CreateServer("http", "localhost", 54321, App);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,12 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
public class MultipleLoopTests
|
public class MultipleLoopTests
|
||||||
{
|
{
|
||||||
private readonly Libuv _uv;
|
private readonly Libuv _uv;
|
||||||
private readonly IKestrelTrace _logger = new KestrelTrace(new TestLogger());
|
private readonly IKestrelTrace _logger;
|
||||||
public MultipleLoopTests()
|
public MultipleLoopTests()
|
||||||
{
|
{
|
||||||
var engine = new KestrelEngine(LibraryManager, new ShutdownNotImplemented(), new TestLogger());
|
var engine = new KestrelEngine(LibraryManager, new TestServiceContext());
|
||||||
_uv = engine.Libuv;
|
_uv = engine.Libuv;
|
||||||
|
_logger = engine.Log;
|
||||||
}
|
}
|
||||||
|
|
||||||
ILibraryManager LibraryManager
|
ILibraryManager LibraryManager
|
||||||
|
|
@ -81,7 +82,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var writeRequest = new UvWriteReq(new KestrelTrace(new TestLogger()));
|
var writeRequest = new UvWriteReq(new KestrelTrace(new TestKestrelTrace()));
|
||||||
writeRequest.Init(loop);
|
writeRequest.Init(loop);
|
||||||
writeRequest.Write(
|
writeRequest.Write(
|
||||||
serverConnectionPipe,
|
serverConnectionPipe,
|
||||||
|
|
@ -100,7 +101,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
{
|
{
|
||||||
var loop2 = new UvLoopHandle(_logger);
|
var loop2 = new UvLoopHandle(_logger);
|
||||||
var clientConnectionPipe = new UvPipeHandle(_logger);
|
var clientConnectionPipe = new UvPipeHandle(_logger);
|
||||||
var connect = new UvConnectRequest(new KestrelTrace(new TestLogger()));
|
var connect = new UvConnectRequest(new KestrelTrace(new TestKestrelTrace()));
|
||||||
|
|
||||||
loop2.Init(_uv);
|
loop2.Init(_uv);
|
||||||
clientConnectionPipe.Init(loop2, true);
|
clientConnectionPipe.Init(loop2, true);
|
||||||
|
|
@ -174,7 +175,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
|
|
||||||
serverConnectionPipeAcceptedEvent.WaitOne();
|
serverConnectionPipeAcceptedEvent.WaitOne();
|
||||||
|
|
||||||
var writeRequest = new UvWriteReq(new KestrelTrace(new TestLogger()));
|
var writeRequest = new UvWriteReq(new KestrelTrace(new TestKestrelTrace()));
|
||||||
writeRequest.Init(loop);
|
writeRequest.Init(loop);
|
||||||
writeRequest.Write2(
|
writeRequest.Write2(
|
||||||
serverConnectionPipe,
|
serverConnectionPipe,
|
||||||
|
|
@ -196,7 +197,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
{
|
{
|
||||||
var loop2 = new UvLoopHandle(_logger);
|
var loop2 = new UvLoopHandle(_logger);
|
||||||
var clientConnectionPipe = new UvPipeHandle(_logger);
|
var clientConnectionPipe = new UvPipeHandle(_logger);
|
||||||
var connect = new UvConnectRequest(new KestrelTrace(new TestLogger()));
|
var connect = new UvConnectRequest(new KestrelTrace(new TestKestrelTrace()));
|
||||||
|
|
||||||
loop2.Init(_uv);
|
loop2.Init(_uv);
|
||||||
clientConnectionPipe.Init(loop2, true);
|
clientConnectionPipe.Init(loop2, true);
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,12 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
public class NetworkingTests
|
public class NetworkingTests
|
||||||
{
|
{
|
||||||
private readonly Libuv _uv;
|
private readonly Libuv _uv;
|
||||||
private readonly IKestrelTrace _logger = new KestrelTrace(new TestLogger());
|
private readonly IKestrelTrace _logger;
|
||||||
public NetworkingTests()
|
public NetworkingTests()
|
||||||
{
|
{
|
||||||
var engine = new KestrelEngine(LibraryManager, new ShutdownNotImplemented(), new TestLogger());
|
var engine = new KestrelEngine(LibraryManager, new TestServiceContext());
|
||||||
_uv = engine.Libuv;
|
_uv = engine.Libuv;
|
||||||
|
_logger = engine.Log;
|
||||||
}
|
}
|
||||||
|
|
||||||
ILibraryManager LibraryManager
|
ILibraryManager LibraryManager
|
||||||
|
|
@ -208,7 +209,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
{
|
{
|
||||||
for (var x = 0; x != 2; ++x)
|
for (var x = 0; x != 2; ++x)
|
||||||
{
|
{
|
||||||
var req = new UvWriteReq(new KestrelTrace(new TestLogger()));
|
var req = new UvWriteReq(new KestrelTrace(new TestKestrelTrace()));
|
||||||
req.Init(loop);
|
req.Init(loop);
|
||||||
req.Write(
|
req.Write(
|
||||||
tcp2,
|
tcp2,
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,13 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using (var kestrelEngine = new KestrelEngine(mockLibuv, new ShutdownNotImplemented(), new TestLogger()))
|
using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
|
||||||
{
|
{
|
||||||
kestrelEngine.Start(count: 1);
|
kestrelEngine.Start(count: 1);
|
||||||
|
|
||||||
var kestrelThread = kestrelEngine.Threads[0];
|
var kestrelThread = kestrelEngine.Threads[0];
|
||||||
var socket = new MockSocket(kestrelThread.Loop.ThreadId, new KestrelTrace(new TestLogger()));
|
var socket = new MockSocket(kestrelThread.Loop.ThreadId, new KestrelTrace(new TestKestrelTrace()));
|
||||||
var trace = new KestrelTrace(new TestLogger());
|
var trace = new KestrelTrace(new TestKestrelTrace());
|
||||||
var socketOutput = new SocketOutput(kestrelThread, socket, 0, trace);
|
var socketOutput = new SocketOutput(kestrelThread, socket, 0, trace);
|
||||||
|
|
||||||
// I doubt _maxBytesPreCompleted will ever be over a MB. If it is, we should change this test.
|
// I doubt _maxBytesPreCompleted will ever be over a MB. If it is, we should change this test.
|
||||||
|
|
@ -77,13 +77,13 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using (var kestrelEngine = new KestrelEngine(mockLibuv, new ShutdownNotImplemented(), new TestLogger()))
|
using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
|
||||||
{
|
{
|
||||||
kestrelEngine.Start(count: 1);
|
kestrelEngine.Start(count: 1);
|
||||||
|
|
||||||
var kestrelThread = kestrelEngine.Threads[0];
|
var kestrelThread = kestrelEngine.Threads[0];
|
||||||
var socket = new MockSocket(kestrelThread.Loop.ThreadId, new KestrelTrace(new TestLogger()));
|
var socket = new MockSocket(kestrelThread.Loop.ThreadId, new KestrelTrace(new TestKestrelTrace()));
|
||||||
var trace = new KestrelTrace(new TestLogger());
|
var trace = new KestrelTrace(new TestKestrelTrace());
|
||||||
var socketOutput = new SocketOutput(kestrelThread, socket, 0, trace);
|
var socketOutput = new SocketOutput(kestrelThread, socket, 0, trace);
|
||||||
|
|
||||||
var bufferSize = maxBytesPreCompleted;
|
var bufferSize = maxBytesPreCompleted;
|
||||||
|
|
|
||||||
|
|
@ -4,20 +4,44 @@ using Microsoft.Framework.Logging;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.KestrelTests
|
namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
{
|
{
|
||||||
public class TestLogger : ILogger
|
public class TestKestrelTrace : KestrelTrace
|
||||||
{
|
{
|
||||||
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
|
public TestKestrelTrace() : base(new TestLogger())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsEnabled(LogLevel logLevel)
|
public override void ConnectionRead(long connectionId, int count)
|
||||||
{
|
{
|
||||||
return false;
|
_logger.LogDebug(1, @"Connection id ""{ConnectionId}"" recv {count} bytes.", connectionId, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDisposable BeginScopeImpl(object state)
|
public override void ConnectionWrite(long connectionId, int count)
|
||||||
{
|
{
|
||||||
return new Disposable(() => { });
|
_logger.LogDebug(1, @"Connection id ""{ConnectionId}"" send {count} bytes.", connectionId, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ConnectionWriteCallback(long connectionId, int status)
|
||||||
|
{
|
||||||
|
_logger.LogDebug(1, @"Connection id ""{ConnectionId}"" send finished with status {status}.", connectionId, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestLogger : ILogger
|
||||||
|
{
|
||||||
|
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Log {logLevel}[{eventId}]: {formatter(state, exception)} {exception?.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEnabled(LogLevel logLevel)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDisposable BeginScopeImpl(object state)
|
||||||
|
{
|
||||||
|
return new Disposable(() => { });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -27,25 +27,29 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
try{
|
try
|
||||||
|
{
|
||||||
var locator = CallContextServiceLocator.Locator;
|
var locator = CallContextServiceLocator.Locator;
|
||||||
if (locator == null)
|
if (locator == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var services = locator.ServiceProvider;
|
var services = locator.ServiceProvider;
|
||||||
if (services == null)
|
if (services == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (ILibraryManager)services.GetService(typeof(ILibraryManager));
|
return (ILibraryManager)services.GetService(typeof(ILibraryManager));
|
||||||
} catch (NullReferenceException) { return null; }
|
}
|
||||||
|
catch (NullReferenceException) { return null; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Create(Func<Frame, Task> app)
|
public void Create(Func<Frame, Task> app)
|
||||||
{
|
{
|
||||||
_engine = new KestrelEngine(LibraryManager, new ShutdownNotImplemented(), new TestLogger());
|
_engine = new KestrelEngine(
|
||||||
|
LibraryManager,
|
||||||
|
new TestServiceContext());
|
||||||
_engine.Start(1);
|
_engine.Start(1);
|
||||||
_server = _engine.CreateServer(
|
_server = _engine.CreateServer(
|
||||||
"http",
|
"http",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
using Microsoft.AspNet.Server.Kestrel;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
|
{
|
||||||
|
public class TestServiceContext : ServiceContext
|
||||||
|
{
|
||||||
|
public TestServiceContext()
|
||||||
|
{
|
||||||
|
AppShutdown = new ShutdownNotImplemented();
|
||||||
|
Log = new TestKestrelTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue