Beispiel #1
0
        private async Task ProduceEndAwaited()
        {
            ProduceStart(appCompleted: true);

            // Force flush
            await SocketOutput.WriteAsync(_emptyData);

            await WriteSuffix();
        }
        public Connection(ListenerContext context, UvStreamHandle socket) : base(context)
        {
            _socket           = socket;
            socket.Connection = this;
            ConnectionControl = this;

            ConnectionId = GenerateConnectionId(Interlocked.Increment(ref _lastConnectionId));

            _rawSocketInput  = new SocketInput(Memory, ThreadPool);
            _rawSocketOutput = new SocketOutput(Thread, _socket, Memory, this, ConnectionId, Log, ThreadPool, WriteReqPool);
        }
Beispiel #3
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 #4
0
        public async Task WriteAsyncAwaited(ArraySegment <byte> data, CancellationToken cancellationToken)
        {
            await ProduceStartAndFireOnStarting();

            if (_autoChunk)
            {
                if (data.Count == 0)
                {
                    return;
                }
                await WriteChunkedAsync(data, cancellationToken);
            }
            else
            {
                await SocketOutput.WriteAsync(data, cancellationToken : cancellationToken);
            }
        }
Beispiel #5
0
        public void Write(ArraySegment <byte> data)
        {
            ProduceStartAndFireOnStarting().GetAwaiter().GetResult();

            if (_autoChunk)
            {
                if (data.Count == 0)
                {
                    return;
                }
                WriteChunked(data);
            }
            else
            {
                SocketOutput.Write(data);
            }
        }
Beispiel #6
0
        public Task WriteAsync(ArraySegment <byte> data, CancellationToken cancellationToken)
        {
            if (!_responseStarted)
            {
                return(WriteAsyncAwaited(data, cancellationToken));
            }

            if (_autoChunk)
            {
                if (data.Count == 0)
                {
                    return(TaskUtilities.CompletedTask);
                }
                return(WriteChunkedAsync(data, cancellationToken));
            }
            else
            {
                return(SocketOutput.WriteAsync(data, cancellationToken: cancellationToken));
            }
        }
 public WriteContext(SocketOutput self)
 {
     Self = self;
 }
Beispiel #8
0
        private void CreateResponseHeader(
            byte[] statusBytes,
            bool appCompleted)
        {
            var responseHeaders = _frameHeaders.ResponseHeaders;

            responseHeaders.SetReadOnly();

            var end = SocketOutput.ProducingStart();

            if (_keepAlive)
            {
                foreach (var connectionValue in responseHeaders.HeaderConnection)
                {
                    if (connectionValue.IndexOf("close", StringComparison.OrdinalIgnoreCase) != -1)
                    {
                        _keepAlive = false;
                    }
                }
            }

            if (_keepAlive && !responseHeaders.HasTransferEncoding && !responseHeaders.HasContentLength)
            {
                if (appCompleted)
                {
                    // Don't set the Content-Length or Transfer-Encoding headers
                    // automatically for HEAD requests or 101, 204, 205, 304 responses.
                    if (Method != "HEAD" && StatusCanHaveBody(StatusCode))
                    {
                        // Since the app has completed and we are only now generating
                        // the headers we can safely set the Content-Length to 0.
                        responseHeaders.SetRawContentLength("0", _bytesContentLengthZero);
                    }
                }
                else
                {
                    if (_httpVersion == HttpVersionType.Http1_1)
                    {
                        _autoChunk = true;
                        responseHeaders.SetRawTransferEncoding("chunked", _bytesTransferEncodingChunked);
                    }
                    else
                    {
                        _keepAlive = false;
                    }
                }
            }

            if (_keepAlive == false && responseHeaders.HasConnection == false && _httpVersion == HttpVersionType.Http1_1)
            {
                responseHeaders.SetRawConnection("close", _bytesConnectionClose);
            }
            else if (_keepAlive && responseHeaders.HasConnection == false && _httpVersion == HttpVersionType.Http1_0)
            {
                responseHeaders.SetRawConnection("keep-alive", _bytesConnectionKeepAlive);
            }

            end.CopyFrom(_httpVersion == HttpVersionType.Http1_1 ? _bytesHttpVersion1_1 : _bytesHttpVersion1_0);
            end.CopyFrom(statusBytes);
            responseHeaders.CopyTo(ref end);
            end.CopyFrom(_bytesEndHeaders, 0, _bytesEndHeaders.Length);

            SocketOutput.ProducingComplete(end);
        }
Beispiel #9
0
 private Task WriteChunkedResponseSuffix()
 {
     return(SocketOutput.WriteAsync(_endChunkedResponseBytes));
 }
Beispiel #10
0
 private Task WriteChunkedAsync(ArraySegment <byte> data, CancellationToken cancellationToken)
 {
     return(SocketOutput.WriteAsync(data, chunk: true, cancellationToken: cancellationToken));
 }
Beispiel #11
0
 private void WriteChunked(ArraySegment <byte> data)
 {
     SocketOutput.Write(data, chunk: true);
 }
Beispiel #12
0
        public async Task FlushAsync(CancellationToken cancellationToken)
        {
            await ProduceStartAndFireOnStarting();

            await SocketOutput.WriteAsync(_emptyData, cancellationToken : cancellationToken);
        }
Beispiel #13
0
 public void Flush()
 {
     ProduceStartAndFireOnStarting().GetAwaiter().GetResult();
     SocketOutput.Write(_emptyData);
 }