Write() public method

public Write ( ArraySegment buffer, Action callback, object state, bool immediate = true, bool socketShutdownSend = false, bool socketDisconnect = false ) : void
buffer ArraySegment
callback Action
state object
immediate bool
socketShutdownSend bool
socketDisconnect bool
return void
Beispiel #1
0
        public void ProduceStart()
        {
            if (_resultStarted)
            {
                return;
            }
            _resultStarted = true;

            FireOnSendingHeaders();

            _headersSent = true;

            var status = ReasonPhrases.ToStatus(StatusCode, ReasonPhrase);

            var responseHeader = CreateResponseHeader(status, ResponseHeaders);

            SocketOutput.Write(
                responseHeader.Item1,
                (error, x) =>
            {
                if (error != null)
                {
                    Trace.WriteLine("ProduceStart " + error.ToString());
                }
                ((IDisposable)x).Dispose();
            },
                responseHeader.Item2);
        }
Beispiel #2
0
        public void ProduceContinue()
        {
            if (_responseStarted)
            {
                return;
            }

            StringValues expect;

            if (_httpVersion == HttpVersionType.Http1_1 &&
                RequestHeaders.TryGetValue("Expect", out expect) &&
                (expect.FirstOrDefault() ?? "").Equals("100-continue", StringComparison.OrdinalIgnoreCase))
            {
                SocketOutput.Write(_continueBytes);
            }
        }
Beispiel #3
0
        public void Write(ArraySegment <byte> data)
        {
            ProduceStartAndFireOnStarting(immediate: false).GetAwaiter().GetResult();

            if (_autoChunk)
            {
                if (data.Count == 0)
                {
                    return;
                }
                WriteChunked(data);
            }
            else
            {
                SocketOutput.Write(data, immediate: true);
            }
        }
Beispiel #4
0
        public void ProduceStart(bool immediate = true, bool appCompleted = false)
        {
            // ProduceStart shouldn't no-op in the future just b/c FireOnStarting throws.
            if (_responseStarted)
            {
                return;
            }
            FireOnStarting();
            _responseStarted = true;

            var status = ReasonPhrases.ToStatus(StatusCode, ReasonPhrase);

            var responseHeader = CreateResponseHeader(status, appCompleted);

            SocketOutput.Write(responseHeader.Item1, immediate: immediate);
            responseHeader.Item2.Dispose();
        }
Beispiel #5
0
        public void Write(ArraySegment <byte> data)
        {
            ProduceStart(immediate: false);

            if (_autoChunk)
            {
                if (data.Count == 0)
                {
                    return;
                }
                WriteChunked(data);
            }
            else
            {
                SocketOutput.Write(data, immediate: true);
            }
        }
        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));
            }
        }
Beispiel #7
0
        public void ProduceContinue()
        {
            if (_resultStarted)
            {
                return;
            }

            string[] expect;
            if (HttpVersion.Equals("HTTP/1.1") &&
                RequestHeaders.TryGetValue("Expect", out expect) &&
                (expect.FirstOrDefault() ?? "").Equals("100-continue", StringComparison.OrdinalIgnoreCase))
            {
                SocketOutput.Write(
                    new ArraySegment <byte>(_continueBytes, 0, _continueBytes.Length),
                    (error, _) =>
                {
                    if (error != null)
                    {
                        Trace.WriteLine("ProduceContinue " + error.ToString());
                    }
                },
                    null);
            }
        }
Beispiel #8
0
 private void WriteChunkedResponseSuffix()
 {
     SocketOutput.Write(_endChunkedResponseBytes, immediate: true);
 }
Beispiel #9
0
 private void WriteChunked(ArraySegment <byte> data)
 {
     SocketOutput.Write(BeginChunkBytes(data.Count), immediate: false);
     SocketOutput.Write(data, immediate: false);
     SocketOutput.Write(_endChunkBytes, immediate: true);
 }
Beispiel #10
0
 public void Flush()
 {
     ProduceStartAndFireOnStarting(immediate: false).GetAwaiter().GetResult();
     SocketOutput.Write(_emptyData, immediate: true);
 }
        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()))
            {
                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);

                var bufferSize = maxBytesPreCompleted;
                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
                // 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));
            }
        }
Beispiel #12
0
 public void Flush()
 {
     ProduceStart(immediate: false);
     SocketOutput.Write(_emptyData, immediate: true);
 }
Beispiel #13
0
 public void Write(ArraySegment <byte> data, Action <Exception, object> callback, object state)
 {
     ProduceStart();
     SocketOutput.Write(data, callback, state);
 }