public static async Task CopyToAsync(this IReadableChannel input, Stream stream)
        {
            while (true)
            {
                await input;

                var fin = input.Completion.IsCompleted;

                var inputBuffer = input.BeginRead();

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    foreach (var span in inputBuffer)
                    {
                        await stream.WriteAsync(span.Array, span.Offset, span.Length);
                    }
                }
                catch (Exception)
                {
                    // REVIEW: Should we do anything here?
                }
                finally
                {
                    input.EndRead(inputBuffer);
                }
            }
        }
        public static async Task CopyToAsync(this IReadableChannel input, IWritableChannel channel)
        {
            while (true)
            {
                await input;

                var fin = input.Completion.IsCompleted;

                var inputBuffer = input.BeginRead();

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    var buffer = channel.Alloc();

                    buffer.Append(inputBuffer);

                    await channel.WriteAsync(buffer);
                }
                finally
                {
                    input.EndRead(inputBuffer);
                }
            }
        }
Exemple #3
0
        public static async Task CopyToAsync(this IReadableChannel input, Stream stream)
        {
            while (true)
            {
                await input;

                var fin = input.Completion.IsCompleted;

                var span = input.BeginRead();

                if (span.Begin.IsEnd && fin)
                {
                    return;
                }

                try
                {
                    await span.Begin.CopyToAsync(stream, span.End.Block);
                }
                finally
                {
                    input.EndRead(span.End);
                }
            }
        }
Exemple #4
0
        private static async Task CopyCompletedAsync(IReadableChannel input, IWritableChannel channel)
        {
            await input;

            do
            {
                var fin = input.Completion.IsCompleted;

                var inputBuffer = input.BeginRead();

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    var buffer = channel.Alloc();

                    buffer.Append(inputBuffer);

                    await channel.WriteAsync(buffer);
                }
                finally
                {
                    input.EndRead(inputBuffer);
                }
            }while (input.IsCompleted);
        }
Exemple #5
0
        private static async Task ReadLines(IReadableChannel channel)
        {
            // Using SIMD to scan through bytes quickly
            var newLine = new Vector <byte>((byte)'\n');

            while (true)
            {
                await channel;

                var iter  = channel.BeginRead().Begin;
                var start = iter;

                // If we're at the end of the channel then stop
                if (iter.IsEnd && channel.Completion.IsCompleted)
                {
                    break;
                }

                try
                {
                    while (iter.Seek(ref newLine) != -1)
                    {
                        // Get the daata from the start to where we found the \n
                        var line = start.GetArraySegment(iter);

                        Console.WriteLine(Encoding.UTF8.GetString(line.Array, line.Offset, line.Count));
                        // Skip /n
                        iter.Skip(1);
                        start = iter;
                    }
                }
                finally
                {
                    channel.EndRead(iter);
                }
            }

            // Tell te channel we're done consuming
            channel.CompleteReading();
        }
Exemple #6
0
        private async void Process(IReadableChannel inner)
        {
            while (true)
            {
                await inner;

                var span = inner.BeginRead();

                if (span.Begin.IsEnd && inner.Completion.IsCompleted)
                {
                    break;
                }

                // PERF: This might copy
                var data = span.Begin.GetArraySegment(span.End);
                var iter = _channel.BeginWrite();
                for (int i = 0; i < data.Count; i++)
                {
                    byte b = data.Array[data.Offset + i];
                    if (b >= 'a' && b <= 'z')
                    {
                        // To upper
                        iter.Write((byte)(b & 0xdf));
                    }
                    else
                    {
                        // Leave it alone
                        iter.Write(b);
                    }
                }

                await _channel.EndWriteAsync(iter);

                inner.EndRead(span.End);
            }

            inner.CompleteReading();

            _channel.CompleteWriting();
        }
Exemple #7
0
            public async Task Execute(IReadableChannel input, IWritableChannel output)
            {
                while (true)
                {
                    await input;

                    var inputBuffer = input.BeginRead();

                    if (inputBuffer.IsEmpty && input.Completion.IsCompleted)
                    {
                        break;
                    }

                    var writerBuffer = output.Alloc(2048);
                    var span         = inputBuffer.FirstSpan;
                    if (span.Length > 0)
                    {
                        _inflater.SetInput(span.BufferPtr, span.Length);

                        int written = _inflater.Inflate(writerBuffer.Memory.BufferPtr, writerBuffer.Memory.Length);

                        writerBuffer.UpdateWritten(written);

                        var consumed = span.Length - _inflater.AvailableInput;

                        inputBuffer = inputBuffer.Slice(0, consumed);
                    }

                    input.EndRead(inputBuffer);

                    await output.WriteAsync(writerBuffer);
                }

                input.CompleteReading();

                output.CompleteWriting();

                _inflater.Dispose();
            }
Exemple #8
0
        private static async Task <int> ReadAsyncAwaited(this IReadableChannel input, byte[] buffer, int offset, int count)
        {
            while (true)
            {
                await input;

                var fin = input.Completion.IsCompleted;

                var begin = input.BeginRead().Begin;
                int actual;
                var end = begin.CopyTo(buffer, offset, count, out actual);
                input.EndRead(end);

                if (actual != 0)
                {
                    return(actual);
                }
                else if (fin)
                {
                    return(0);
                }
            }
        }
Exemple #9
0
        public static ValueTask <int> ReadAsync(this IReadableChannel input, byte[] buffer, int offset, int count)
        {
            while (input.IsCompleted)
            {
                var fin = input.Completion.IsCompleted;

                var begin = input.BeginRead().Begin;
                int actual;
                var end = begin.CopyTo(buffer, offset, count, out actual);
                input.EndRead(end);

                if (actual != 0)
                {
                    return(new ValueTask <int>(actual));
                }
                else if (fin)
                {
                    return(new ValueTask <int>(0));
                }
            }

            return(new ValueTask <int>(input.ReadAsyncAwaited(buffer, offset, count)));
        }
        public static ValueTask <int> ReadAsync(this IReadableChannel input, byte[] buffer, int offset, int count)
        {
            while (input.IsCompleted)
            {
                var fin = input.Completion.IsCompleted;

                var inputBuffer = input.BeginRead();
                var sliced      = inputBuffer.Slice(0, count);
                sliced.CopyTo(buffer, offset);
                int actual = sliced.Length;
                input.EndRead(sliced);

                if (actual != 0)
                {
                    return(new ValueTask <int>(actual));
                }
                else if (fin)
                {
                    return(new ValueTask <int>(0));
                }
            }

            return(new ValueTask <int>(input.ReadAsyncAwaited(buffer, offset, count)));
        }
        private static async Task <int> ReadAsyncAwaited(this IReadableChannel input, byte[] buffer, int offset, int count)
        {
            while (true)
            {
                await input;

                var fin = input.Completion.IsCompleted;

                var inputBuffer = input.BeginRead();
                var sliced      = inputBuffer.Slice(0, count);
                sliced.CopyTo(buffer, offset);
                int actual = sliced.Length;
                input.EndRead(sliced);

                if (actual != 0)
                {
                    return(actual);
                }
                else if (fin)
                {
                    return(0);
                }
            }
        }
Exemple #12
0
            public async Task Execute(IReadableChannel input, IWritableChannel output)
            {
                while (true)
                {
                    await input;

                    var inputBuffer = input.BeginRead();

                    if (inputBuffer.IsEmpty && input.Completion.IsCompleted)
                    {
                        break;
                    }

                    var writerBuffer = output.Alloc(2048);
                    var span         = inputBuffer.FirstSpan;

                    _deflater.SetInput(span.BufferPtr, span.Length);

                    while (!_deflater.NeedsInput())
                    {
                        int written = _deflater.ReadDeflateOutput(writerBuffer.Memory.BufferPtr, writerBuffer.Memory.Length);
                        writerBuffer.UpdateWritten(written);
                    }

                    var consumed = span.Length - _deflater.AvailableInput;

                    inputBuffer = inputBuffer.Slice(0, consumed);

                    input.EndRead(inputBuffer);

                    await output.WriteAsync(writerBuffer);
                }

                bool flushed;

                do
                {
                    // Need to do more stuff here
                    var writerBuffer = output.Alloc(2048);

                    int compressedBytes;
                    flushed = _deflater.Flush(writerBuffer.Memory.BufferPtr, writerBuffer.Memory.Length, out compressedBytes);
                    writerBuffer.UpdateWritten(compressedBytes);

                    await output.WriteAsync(writerBuffer);
                }while (flushed);

                bool finished;

                do
                {
                    // Need to do more stuff here
                    var writerBuffer = output.Alloc(2048);

                    int compressedBytes;
                    finished = _deflater.Finish(writerBuffer.Memory.BufferPtr, writerBuffer.Memory.Length, out compressedBytes);
                    writerBuffer.UpdateWritten(compressedBytes);

                    await output.WriteAsync(writerBuffer);
                }while (!finished);

                input.CompleteReading();

                output.CompleteWriting();

                _deflater.Dispose();
            }
Exemple #13
0
        public async Task ProcessAllRequests()
        {
            Reset();

            while (true)
            {
                await _input;

                var  buffer       = _input.BeginRead();
                var  consumed     = buffer.Start;
                bool needMoreData = true;

                try
                {
                    if (buffer.IsEmpty && _input.Completion.IsCompleted)
                    {
                        // We're done with this connection
                        return;
                    }

                    if (_state == ParsingState.StartLine)
                    {
                        // Find \n
                        var delim = buffer.IndexOf(ref _vectorLFs);
                        if (delim.IsEnd)
                        {
                            continue;
                        }

                        // Grab the entire start line
                        var startLine = buffer.Slice(0, delim);

                        // Move the buffer to the rest
                        buffer = buffer.Slice(delim).Slice(1);

                        delim = startLine.IndexOf(ref _vectorSpaces);
                        if (delim.IsEnd)
                        {
                            throw new Exception();
                        }

                        var method = startLine.Slice(0, delim);
                        Method = method.Clone();

                        // Skip ' '
                        startLine = startLine.Slice(delim).Slice(1);

                        delim = startLine.IndexOf(ref _vectorSpaces);
                        if (delim.IsEnd)
                        {
                            throw new Exception();
                        }

                        var path = startLine.Slice(0, delim);
                        Path = path.Clone();

                        // Skip ' '
                        startLine = startLine.Slice(delim).Slice(1);

                        delim = startLine.IndexOf(ref _vectorCRs);
                        if (delim.IsEnd)
                        {
                            throw new Exception();
                        }

                        var httpVersion = startLine.Slice(0, delim);
                        HttpVersion = httpVersion.Clone();

                        _state   = ParsingState.Headers;
                        consumed = startLine.End;
                    }

                    // Parse headers
                    // key: value\r\n

                    while (!buffer.IsEmpty)
                    {
                        var ch = buffer.Peek();

                        if (ch == -1)
                        {
                            break;
                        }

                        if (ch == '\r')
                        {
                            // Check for final CRLF.
                            buffer = buffer.Slice(1);
                            ch     = buffer.Peek();
                            buffer = buffer.Slice(1);

                            if (ch == -1)
                            {
                                break;
                            }
                            else if (ch == '\n')
                            {
                                consumed     = buffer.Start;
                                needMoreData = false;
                                break;
                            }

                            // Headers don't end in CRLF line.
                            throw new Exception();
                        }

                        var headerName  = default(ReadableBuffer);
                        var headerValue = default(ReadableBuffer);

                        // End of the header
                        // \n
                        var delim = buffer.IndexOf(ref _vectorLFs);
                        if (delim.IsEnd)
                        {
                            break;
                        }

                        var headerPair = buffer.Slice(0, delim);
                        buffer = buffer.Slice(delim).Slice(1);

                        // :
                        delim = headerPair.IndexOf(ref _vectorColons);
                        if (delim.IsEnd)
                        {
                            throw new Exception();
                        }

                        headerName = headerPair.Slice(0, delim).TrimStart();
                        headerPair = headerPair.Slice(delim).Slice(1);

                        // \r
                        delim = headerPair.IndexOf(ref _vectorCRs);
                        if (delim.IsEnd)
                        {
                            // Bad request
                            throw new Exception();
                        }

                        headerValue = headerPair.Slice(0, delim).TrimStart();
                        RequestHeaders.SetHeader(ref headerName, ref headerValue);

                        // Move the consumed
                        consumed = buffer.Start;
                    }
                }
                catch (Exception)
                {
                    StatusCode = 400;

                    await EndResponse();

                    return;
                }
                finally
                {
                    _input.EndRead(consumed);
                }

                if (needMoreData)
                {
                    continue;
                }

                var context = _application.CreateContext(this);

                try
                {
                    await _application.ProcessRequestAsync(context);
                }
                catch (Exception ex)
                {
                    StatusCode = 500;

                    _application.DisposeContext(context, ex);
                }
                finally
                {
                    await EndResponse();
                }

                if (!KeepAlive)
                {
                    break;
                }

                Reset();
            }
        }