상속: ServiceContext, IDisposable
예제 #1
0
 public IDisposable Start(IServerInformation serverInformation, Func<IFeatureCollection, Task> application)
 {
     var disposables = new List<IDisposable>();
     var information = (ServerInformation)serverInformation;
     var engine = new KestrelEngine(_libraryManager, _appShutdownService);
     engine.Start(1);
     foreach (var address in information.Addresses)
     {
         disposables.Add(engine.CreateServer(
             address.Scheme,
             address.Host,
             address.Port,
             async frame =>
             {
                 var request = new ServerRequest(frame);
                 await application.Invoke(request.Features);
             }));
     }
     disposables.Add(engine);
     return new Disposable(() =>
     {
         foreach (var disposable in disposables)
         {
             disposable.Dispose();
         }
     });
 }
 public KestrelThread(KestrelEngine engine)
 {
     _engine = engine;
     _loop = new UvLoopHandle();
     _post = new UvAsyncHandle();
     _thread = new Thread(ThreadStart);
     QueueCloseHandle = PostCloseHandle;
 }
예제 #3
0
 public KestrelThread(KestrelEngine engine)
 {
     _engine          = engine;
     _loop            = new UvLoopHandle();
     _post            = new UvAsyncHandle();
     _thread          = new Thread(ThreadStart);
     QueueCloseHandle = PostCloseHandle;
 }
예제 #4
0
 public async Task ListenerCanCreateAndDispose()
 {
     var engine = new KestrelEngine(LibraryManager);
     engine.Start(1);
     var started = engine.CreateServer("http", "localhost", 54321, App);
     started.Dispose();
     engine.Dispose();
 }
예제 #5
0
 public void Create(Func<IFeatureCollection, Task> app, ServiceContext context, string serverAddress)
 {
     _engine = new KestrelEngine(context);
     _engine.Start(1);
     _server = _engine.CreateServer(
         ServerAddress.FromUrl(serverAddress),
         app);
 }
 public KestrelThread(KestrelEngine engine)
 {
     _engine          = engine;
     _appShutdown     = engine.AppShutdown;
     _log             = engine.Log;
     _loop            = new UvLoopHandle(_log);
     _post            = new UvAsyncHandle(_log);
     _thread          = new Thread(ThreadStart);
     QueueCloseHandle = PostCloseHandle;
 }
예제 #7
0
 public void Create(Func<Frame, Task> app)
 {
     _engine = new KestrelEngine(LibraryManager);
     _engine.Start(1);
     _server = _engine.CreateServer(
         "http",
         "localhost",
         54321,
         app);
 }
        public void WritesDontCompleteImmediatelyWhenTooManyBytesAreAlreadyPreCompleted()
        {
            // This should match _maxBytesPreCompleted in SocketOutput
            var maxBytesPreCompleted = 65536;
            var completeQueue = new Queue<Action<int>>();

            // Arrange
            var mockLibuv = new MockLibuv
            {
                OnWrite = (socket, buffers, triggerCompleted) =>
                {
                    completeQueue.Enqueue(triggerCompleted);
                    return 0;
                }
            };

            using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
            using (var memory = new MemoryPool2())
            {
                kestrelEngine.Start(count: 1);

                var kestrelThread = kestrelEngine.Threads[0];
                var socket = new MockSocket(kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                var trace = new KestrelTrace(new TestKestrelTrace());
                var ltp = new LoggingThreadPool(trace);
                var socketOutput = new SocketOutput(kestrelThread, socket, memory, null, 0, trace, ltp, new Queue<UvWriteReq>());

                var bufferSize = maxBytesPreCompleted;
                var buffer = new ArraySegment<byte>(new byte[bufferSize], 0, bufferSize);
                var completedWh = new ManualResetEventSlim();
                Action<Task> onCompleted = (Task t) =>
                {
                    Assert.Null(t.Exception);
                    completedWh.Set();
                };

                // Act 
                socketOutput.WriteAsync(buffer).ContinueWith(onCompleted);
                // Assert
                // The first write should pre-complete since it is <= _maxBytesPreCompleted.
                Assert.True(completedWh.Wait(1000));
                // Arrange
                completedWh.Reset();
                // Act
                socketOutput.WriteAsync(buffer).ContinueWith(onCompleted);
                // Assert 
                // Too many bytes are already pre-completed for the second write to pre-complete.
                Assert.False(completedWh.Wait(1000));
                // Act
                completeQueue.Dequeue()(0);
                // Assert
                // Finishing the first write should allow the second write to pre-complete.
                Assert.True(completedWh.Wait(1000));
            }
        }
예제 #9
0
 public void Create(RequestDelegate app, ServiceContext context, string serverAddress)
 {
     context.FrameFactory = (connectionContext, remoteEP, localEP, prepareRequest) => 
     {
         return new Frame<HttpContext>(new DummyApplication(app), connectionContext, remoteEP, localEP, prepareRequest);
     };
     _engine = new KestrelEngine(context);
     _engine.Start(1);
     _server = _engine.CreateServer(
         ServerAddress.FromUrl(serverAddress));
 }
예제 #10
0
 public KestrelThread(KestrelEngine engine)
 {
     _engine          = engine;
     _appLifetime     = engine.AppLifetime;
     _log             = engine.Log;
     _threadPool      = engine.ThreadPool;
     _loop            = new UvLoopHandle(_log);
     _post            = new UvAsyncHandle(_log);
     _thread          = new Thread(ThreadStart);
     _thread.Name     = "KestrelThread - libuv";
     QueueCloseHandle = PostCloseHandle;
 }
예제 #11
0
        public void WritesDontCompleteImmediatelyWhenTooManyBytesAreAlreadyPreCompleted()
        {
            // This should match _maxBytesPreCompleted in SocketOutput
            var maxBytesPreCompleted = 65536;
            var completeQueue = new Queue<Action<int>>();

            // Arrange
            var mockLibuv = new MockLibuv
            {
                OnWrite = (socket, buffers, triggerCompleted) =>
                {
                    completeQueue.Enqueue(triggerCompleted);
                    return 0;
                }
            };

            using (var kestrelEngine = new KestrelEngine(mockLibuv, new ShutdownNotImplemented()))
            {
                kestrelEngine.Start(count: 1);

                var kestrelThread = kestrelEngine.Threads[0];
                var socket = new MockSocket(kestrelThread.Loop.ThreadId);
                var socketOutput = new SocketOutput(kestrelThread, socket);

                var bufferSize = maxBytesPreCompleted;
                var buffer = new ArraySegment<byte>(new byte[bufferSize], 0, bufferSize);
                var completedWh = new ManualResetEventSlim();
                Action<Exception, object> onCompleted = (ex, state) =>
                {
                    Assert.Null(ex);
                    Assert.Null(state);
                    completedWh.Set();
                };

                // Act
                socketOutput.Write(buffer, onCompleted, null);
                // Assert
                // The first write should pre-complete since it is <= _maxBytesPreCompleted.
                Assert.True(completedWh.Wait(1000));
                // Arrange
                completedWh.Reset();
                // Act
                socketOutput.Write(buffer, onCompleted, null);
                // Assert
                // Too many bytes are already pre-completed for the second write to pre-complete.
                Assert.False(completedWh.Wait(1000));
                // Act
                completeQueue.Dequeue()(0);
                // Assert
                // Finishing the first write should allow the second write to pre-complete.
                Assert.True(completedWh.Wait(1000));
            }
        }
예제 #12
0
 public KestrelThread(KestrelEngine engine)
 {
     _engine = engine;
     _appLifetime = engine.AppLifetime;
     _log = engine.Log;
     _threadPool = engine.ThreadPool;
     _loop = new UvLoopHandle(_log);
     _post = new UvAsyncHandle(_log);
     _thread = new Thread(ThreadStart);
     _thread.Name = "KestrelThread - libuv";
     QueueCloseHandle = PostCloseHandle;
 }
        public void CanWrite1MB()
        {
            // This test was added because when initially implementing write-behind buffering in
            // SocketOutput, the write callback would never be invoked for writes larger than
            // _maxBytesPreCompleted even after the write actually completed.

            // Arrange
            var mockLibuv = new MockLibuv
            {
                OnWrite = (socket, buffers, triggerCompleted) =>
                {
                    triggerCompleted(0);
                    return 0;
                }
            };

            using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
            using (var memory = new MemoryPool2())
            {
                kestrelEngine.Start(count: 1);

                var kestrelThread = kestrelEngine.Threads[0];
                var socket = new MockSocket(kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                var trace = new KestrelTrace(new TestKestrelTrace());
                var ltp = new LoggingThreadPool(trace);
                var socketOutput = new SocketOutput(kestrelThread, socket, memory, null, 0, trace, ltp, new Queue<UvWriteReq>());

                // I doubt _maxBytesPreCompleted will ever be over a MB. If it is, we should change this test.
                var bufferSize = 1048576;
                var buffer = new ArraySegment<byte>(new byte[bufferSize], 0, bufferSize);
                var completedWh = new ManualResetEventSlim();

                // Act
                socketOutput.WriteAsync(buffer).ContinueWith(
                    (t) =>
                    {
                        Assert.Null(t.Exception);
                        completedWh.Set();
                    }
                );

                // Assert
                Assert.True(completedWh.Wait(1000));
            }
        }
        public void CanWrite1MB()
        {
            // This test was added because when initially implementing write-behind buffering in
            // SocketOutput, the write callback would never be invoked for writes larger than
            // _maxBytesPreCompleted even after the write actually completed.

            // Arrange
            var mockLibuv = new MockLibuv
            {
                OnWrite = (socket, buffers, triggerCompleted) =>
                {
                    triggerCompleted(0);
                    return 0;
                }
            };

            using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
            {
                kestrelEngine.Start(count: 1);

                var kestrelThread = kestrelEngine.Threads[0];
                var socket = new MockSocket(kestrelThread.Loop.ThreadId, new KestrelTrace(new TestKestrelTrace()));
                var trace = new KestrelTrace(new TestKestrelTrace());
                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.
                var bufferSize = 1048576;
                var buffer = new ArraySegment<byte>(new byte[bufferSize], 0, bufferSize);
                var completedWh = new ManualResetEventSlim();
                Action<Exception, object, bool> onCompleted = (ex, state, calledInline) =>
                {
                    Assert.Null(ex);
                    Assert.Null(state);
                    completedWh.Set();
                };

                // Act
                socketOutput.Write(buffer, onCompleted, null);

                // Assert
                Assert.True(completedWh.Wait(1000));
            }
        }
예제 #15
0
        public void ConnectionCanReadAndWrite(ServiceContext testContext)
        {
            var engine = new KestrelEngine(testContext);
            engine.Start(1);
            var address = ServerAddress.FromUrl("http://localhost:54321/");
            var started = engine.CreateServer(address, App);

            Console.WriteLine("Started");
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            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];
            while (true)
            {
                var length = socket.Receive(buffer);
                if (length == 0) { break; }
                var text = Encoding.ASCII.GetString(buffer, 0, length);
            }
            started.Dispose();
            engine.Dispose();
        }
예제 #16
0
 public NetworkingTests()
 {
     var engine = new KestrelEngine(LibraryManager, new ShutdownNotImplemented());
     _uv = engine.Libuv;
 }
예제 #17
0
 public async Task EngineCanStartAndStop()
 {
     var engine = new KestrelEngine(LibraryManager);
     engine.Start(1);
     engine.Dispose();
 }
        public void WritesDontGetCompletedTooQuickly()
        {
            // This should match _maxBytesPreCompleted in SocketOutput
            var maxBytesPreCompleted = 65536;
            var completeQueue = new Queue<Action<int>>();
            var onWriteWh = new ManualResetEventSlim();

            // Arrange
            var mockLibuv = new MockLibuv
            {
                OnWrite = (socket, buffers, triggerCompleted) =>
                {
                    completeQueue.Enqueue(triggerCompleted);
                    onWriteWh.Set();

                    return 0;
                }
            };

            using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
            using (var memory = new MemoryPool2())
            {
                kestrelEngine.Start(count: 1);

                var kestrelThread = kestrelEngine.Threads[0];
                var socket = new MockSocket(kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                var trace = new KestrelTrace(new TestKestrelTrace());
                var ltp = new LoggingThreadPool(trace);
                var socketOutput = new SocketOutput(kestrelThread, socket, memory, null, 0, trace, ltp, new Queue<UvWriteReq>());

                var bufferSize = maxBytesPreCompleted;
                var buffer = new ArraySegment<byte>(new byte[bufferSize], 0, bufferSize);

                var completedWh = new ManualResetEventSlim();
                Action<Task> onCompleted = (Task t) =>
                {
                    Assert.Null(t.Exception);
                    completedWh.Set();
                };

                var completedWh2 = new ManualResetEventSlim();
                Action<Task> onCompleted2 = (Task t) =>
                {
                    Assert.Null(t.Exception);
                    completedWh2.Set();
                };

                // Act (Pre-complete the maximum number of bytes in preparation for the rest of the test)
                socketOutput.WriteAsync(buffer).ContinueWith(onCompleted);
                // Assert
                // The first write should pre-complete since it is <= _maxBytesPreCompleted.
                Assert.True(completedWh.Wait(1000));
                Assert.True(onWriteWh.Wait(1000));
                // Arrange
                completedWh.Reset();
                onWriteWh.Reset();

                // Act
                socketOutput.WriteAsync(buffer).ContinueWith(onCompleted);
                socketOutput.WriteAsync(buffer).ContinueWith(onCompleted2);

                Assert.True(onWriteWh.Wait(1000));
                completeQueue.Dequeue()(0);

                // Assert 
                // Too many bytes are already pre-completed for the third but not the second write to pre-complete.
                // https://github.com/aspnet/KestrelHttpServer/issues/356
                Assert.True(completedWh.Wait(1000));
                Assert.False(completedWh2.Wait(1000));

                // Act
                completeQueue.Dequeue()(0);

                // Assert
                // Finishing the first write should allow the second write to pre-complete.
                Assert.True(completedWh2.Wait(1000));
            }
        }
예제 #19
0
 public void ListenerCanCreateAndDispose()
 {
     var engine = new KestrelEngine(LibraryManager, new ShutdownNotImplemented());
     engine.Start(1);
     var started = engine.CreateServer("http", "localhost", 54321, App);
     started.Dispose();
     engine.Dispose();
 }
예제 #20
0
        public void ConnectionCanReadAndWrite()
        {
            var engine = new KestrelEngine(LibraryManager, new ShutdownNotImplemented());
            engine.Start(1);
            var started = engine.CreateServer("http", "localhost", 54321, App);

            Console.WriteLine("Started");
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            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];
            for (; ;)
            {
                var length = socket.Receive(buffer);
                if (length == 0) { break; }
                var text = Encoding.ASCII.GetString(buffer, 0, length);
            }
            started.Dispose();
            engine.Dispose();
        }
 public NetworkingTests()
 {
     var engine = new KestrelEngine(LibraryManager);
     _uv = engine.Libuv;
 }
예제 #22
0
        public IDisposable Start(IFeatureCollection serverFeatures, Func<IFeatureCollection, Task> application)
        {
            var disposables = new Stack<IDisposable>();
            var disposer = new Disposable(() =>
            {
                foreach (var disposable in disposables)
                {
                    disposable.Dispose();
                }
            });

            try
            {
                var information = (KestrelServerInformation)serverFeatures.Get<IKestrelServerInformation>();
                var dateHeaderValueManager = new DateHeaderValueManager();
                var engine = new KestrelEngine(_libraryManager, new ServiceContext
                {
                    AppShutdown = _appShutdownService,
                    Log = new KestrelTrace(_logger),
                    DateHeaderValueManager = dateHeaderValueManager
                });

                disposables.Push(engine);
                disposables.Push(dateHeaderValueManager);

                if (information.ThreadCount < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(information.ThreadCount),
                        information.ThreadCount,
                        "ThreadCount cannot be negative");
                }

                engine.Start(information.ThreadCount == 0 ? 1 : information.ThreadCount);
                bool atLeastOneListener = false;

                foreach (var address in information.Addresses)
                {
                    var parsedAddress = ServerAddress.FromUrl(address);
                    if (parsedAddress == null)
                    {
                        throw new FormatException("Unrecognized listening address: " + address);
                    }
                    else
                    {
                        atLeastOneListener = true;
                        disposables.Push(engine.CreateServer(
                            parsedAddress.Scheme,
                            parsedAddress.Host,
                            parsedAddress.Port,
                            async frame =>
                            {
                                var request = new ServerRequest(frame);
                                await application.Invoke(request.Features).ConfigureAwait(false);
                            }));
                    }
                }

                if (!atLeastOneListener)
                {
                    throw new InvalidOperationException("No recognized listening addresses were configured.");
                }

                return disposer;
            }
            catch
            {
                disposer.Dispose();
                throw;
            }
        }
예제 #23
0
 public void EngineCanStartAndStop()
 {
     var engine = new KestrelEngine(LibraryManager, new TestServiceContext());
     engine.Start(1);
     engine.Dispose();
 }
예제 #24
0
 public void ListenerCanCreateAndDispose()
 {
     var engine = new KestrelEngine(LibraryManager, new TestServiceContext());
     engine.Start(1);
     var started = engine.CreateServer("http", "localhost", 54321, App);
     started.Dispose();
     engine.Dispose();
 }
        public void ProducingStartAndProducingCompleteCanBeUsedDirectly()
        {
            int nBuffers = 0;
            var nBufferWh = new ManualResetEventSlim();

            var mockLibuv = new MockLibuv
            {
                OnWrite = (socket, buffers, triggerCompleted) =>
                {
                    nBuffers = buffers;
                    nBufferWh.Set();
                    triggerCompleted(0);
                    return 0;
                }
            };

            using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext()))
            using (var memory = new MemoryPool2())
            {
                kestrelEngine.Start(count: 1);

                var kestrelThread = kestrelEngine.Threads[0];
                var socket = new MockSocket(kestrelThread.Loop.ThreadId, new TestKestrelTrace());
                var trace = new KestrelTrace(new TestKestrelTrace());
                var ltp = new LoggingThreadPool(trace);
                var socketOutput = new SocketOutput(kestrelThread, socket, memory, null, 0, trace, ltp, new Queue<UvWriteReq>());

                // block 1
                var start = socketOutput.ProducingStart();
                start.Block.End = start.Block.Data.Offset + start.Block.Data.Count;

                // block 2
                var block2 = memory.Lease();
                block2.End = block2.Data.Offset + block2.Data.Count;
                start.Block.Next = block2;

                var end = new MemoryPoolIterator2(block2, block2.End);

                socketOutput.ProducingComplete(end);

                // A call to Write is required to ensure a write is scheduled
                socketOutput.WriteAsync(default(ArraySegment<byte>));

                Assert.True(nBufferWh.Wait(1000));
                Assert.Equal(2, nBuffers);
            }
        }
예제 #26
0
 public void EngineCanStartAndStop(ServiceContext testContext)
 {
     var engine = new KestrelEngine(testContext);
     engine.Start(1);
     engine.Dispose();
 }
예제 #27
0
 public void ListenerCanCreateAndDispose(ServiceContext testContext)
 {
     var engine = new KestrelEngine(testContext);
     engine.Start(1);
     var address = ServerAddress.FromUrl("http://localhost:54321/");
     var started = engine.CreateServer(address, App);
     started.Dispose();
     engine.Dispose();
 }
예제 #28
0
        public IDisposable Start(IFeatureCollection serverFeatures, Func <IFeatureCollection, Task> application)
        {
            var disposables = new Stack <IDisposable>();
            var disposer    = new Disposable(() =>
            {
                foreach (var disposable in disposables)
                {
                    disposable.Dispose();
                }
            });

            try
            {
                var information            = (KestrelServerInformation)serverFeatures.Get <IKestrelServerInformation>();
                var dateHeaderValueManager = new DateHeaderValueManager();
                var engine = new KestrelEngine(_libraryManager, new ServiceContext
                {
                    AppShutdown            = _appShutdownService,
                    Log                    = new KestrelTrace(_logger),
                    DateHeaderValueManager = dateHeaderValueManager
                });

                disposables.Push(engine);
                disposables.Push(dateHeaderValueManager);

                if (information.ThreadCount < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(information.ThreadCount),
                                                          information.ThreadCount,
                                                          "ThreadCount cannot be negative");
                }

                engine.Start(information.ThreadCount == 0 ? 1 : information.ThreadCount);
                bool atLeastOneListener = false;

                foreach (var address in information.Addresses)
                {
                    var parsedAddress = ServerAddress.FromUrl(address);
                    if (parsedAddress == null)
                    {
                        throw new FormatException("Unrecognized listening address: " + address);
                    }
                    else
                    {
                        atLeastOneListener = true;
                        disposables.Push(engine.CreateServer(
                                             parsedAddress.Scheme,
                                             parsedAddress.Host,
                                             parsedAddress.Port,
                                             async frame =>
                        {
                            var request = new ServerRequest(frame);
                            await application.Invoke(request.Features).ConfigureAwait(false);
                        }));
                    }
                }

                if (!atLeastOneListener)
                {
                    throw new InvalidOperationException("No recognized listening addresses were configured.");
                }

                return(disposer);
            }
            catch
            {
                disposer.Dispose();
                throw;
            }
        }
예제 #29
0
 public void EngineCanStartAndStop()
 {
     var engine = new KestrelEngine(LibraryManager, new ShutdownNotImplemented());
     engine.Start(1);
     engine.Dispose();
 }
 public NetworkingTests()
 {
     var engine = new KestrelEngine(new TestServiceContext());
     _uv = engine.Libuv;
     _logger = engine.Log;
 }
 public MultipleLoopTests()
 {
     var engine = new KestrelEngine(new TestServiceContext());
     _uv = engine.Libuv;
     _logger = engine.Log;
 }
예제 #32
0
 public MultipleLoopTests()
 {
     var engine = new KestrelEngine(LibraryManager, new ShutdownNotImplemented());
     _uv = engine.Libuv;
 }