コード例 #1
0
        public async Task StartAsync(IConnectionHandler connectionHandler)
        {
            try
            {
                _connectionContext = connectionHandler.OnConnection(this);

                _input  = _connectionContext.Input;
                _output = _connectionContext.Output;

                // Spawn send and receive logic
                Task receiveTask = DoReceive();
                Task sendTask    = DoSend();

                // If the sending task completes then close the receive
                // We don't need to do this in the other direction because the kestrel
                // will trigger the output closing once the input is complete.
                if (await Task.WhenAny(receiveTask, sendTask) == sendTask)
                {
                    // Tell the reader it's being aborted
                    _socket.Dispose();
                }

                // Now wait for both to complete
                await receiveTask;
                await sendTask;

                // Dispose the socket(should noop if already called)
                _socket.Dispose();
            }
            catch (Exception)
            {
                // TODO: Log
            }
        }
コード例 #2
0
ファイル: PipeExtensions.cs プロジェクト: WinCPP/corefxlab
        public static Task WriteAsync(this IPipeWriter output, ArraySegment <byte> source)
        {
            var writeBuffer = output.Alloc();

            writeBuffer.Write(source);
            return(FlushAsync(writeBuffer));
        }
コード例 #3
0
        public static async void Echo(IPipeReader input, IPipeWriter output)
        {
            try
            {
                while (true)
                {
                    var result = await input.ReadAsync();

                    var request = result.Buffer;

                    if (request.IsEmpty && result.IsCompleted)
                    {
                        input.Advance(request.End);
                        break;
                    }

                    int len      = request.Length;
                    var response = output.Alloc();
                    response.Append(request);
                    await response.FlushAsync();

                    input.Advance(request.End);
                }
            }
            catch
            {
                input.Complete();
                output.Complete();
            }
        }
コード例 #4
0
        public static async Task WriteAsync(this IPipeWriter output, Span <byte> source)
        {
            var writeBuffer = output.Alloc();

            writeBuffer.Write(source);
            await writeBuffer.FlushAsync();
        }
コード例 #5
0
        public static async Task CopyToAsync(this IPipeReader input, IPipeWriter output)
        {
            while (true)
            {
                var result = await input.ReadAsync();

                var inputBuffer = result.Buffer;

                var fin = result.IsCompleted;

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

                    var buffer = output.Alloc();

                    buffer.Append(inputBuffer);

                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }
            }
        }
コード例 #6
0
        public static Task WriteAsync(this IPipeWriter output, Span <byte> source)
        {
            var writeBuffer = output.Alloc();

            writeBuffer.Write(source);
            return(AwaitFlushAsync(writeBuffer));
        }
コード例 #7
0
        public static async Task CopyToAsync(this IPipeReader input, IPipeWriter output)
        {
            while (true)
            {
                var result = await input.ReadAsync();

                var inputBuffer = result.Buffer;

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

                    var buffer = output.Alloc();

                    foreach (var memory in inputBuffer)
                    {
                        buffer.Write(memory.Span);
                    }


                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }
            }
        }
コード例 #8
0
            public async Task Execute(IPipeReader reader, IPipeWriter writer)
            {
                List <MemoryHandle> handles = new List <MemoryHandle>();

                while (true)
                {
                    var result = await reader.ReadAsync();

                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty)
                    {
                        if (result.IsCompleted)
                        {
                            break;
                        }

                        reader.Advance(inputBuffer.End);
                        continue;
                    }

                    var writerBuffer = writer.Alloc();
                    var buffer       = inputBuffer.First;
                    if (buffer.Length > 0)
                    {
                        unsafe
                        {
                            var handle = buffer.Retain(pin: true);
                            handles.Add(handle);
                            _inflater.SetInput((IntPtr)handle.PinnedPointer, buffer.Length);

                            writerBuffer.Ensure();
                            handle = writerBuffer.Buffer.Retain(pin: true);
                            handles.Add(handle);
                            int written = _inflater.Inflate((IntPtr)handle.PinnedPointer, writerBuffer.Buffer.Length);
                            writerBuffer.Advance(written);

                            var consumed = buffer.Length - _inflater.AvailableInput;

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

                    reader.Advance(inputBuffer.End);

                    await writerBuffer.FlushAsync();
                }

                reader.Complete();

                writer.Complete();

                _inflater.Dispose();

                foreach (var handle in handles)
                {
                    handle.Dispose();
                }
            }
コード例 #9
0
 public HttpConnection(IHttpApplication <TContext> application, IPipeReader input, IPipeWriter output)
 {
     _application  = application;
     _input        = input;
     _output       = output;
     _requestBody  = new HttpRequestStream <TContext>(this);
     _responseBody = new HttpResponseStream <TContext>(this);
 }
コード例 #10
0
        public static IPipeWriter CreateGZipCompressWriter(PipeOptions options, IPipeWriter writer, CompressionLevel compressionLevel)
        {
            var deflater = new WritableDeflateTransform(compressionLevel, ZLibNative.GZip_DefaultWindowBits);
            var pipe     = new Pipe(options);
            var ignore   = deflater.Execute(pipe.Reader, writer);

            return(pipe.Writer);
        }
コード例 #11
0
        public static IPipeWriter CreateGZipCompressWriter(this PipeFactory factory, IPipeWriter writer, CompressionLevel compressionLevel)
        {
            var deflater = new WritableDeflateTransform(compressionLevel, ZLibNative.GZip_DefaultWindowBits);
            var pipe     = factory.Create();
            var ignore   = deflater.Execute(pipe.Reader, writer);

            return(pipe.Writer);
        }
コード例 #12
0
 public override void Shutdown()
 {
     base.Shutdown();
     if (Pipe != null)
     {
         Pipe.Dispose();
         Pipe = null;
     }
 }
コード例 #13
0
        public IPipeWriter CreateWriter(IPipeWriter writer, Func <IPipeReader, IPipeWriter, Task> consume)
        {
            var pipe = new Pipe(_pool);

            consume(pipe, writer).ContinueWith(t =>
            {
            });

            return(pipe);
        }
コード例 #14
0
 // filtering test function for writer
 public static IPipeWriter Filter0xf0(this PipeFactory pfac, IPipeWriter writer)
 {
     return(pfac.CreateWriter(writer, async(r, w) =>
     {
         while (true)
         {
             var wbuf = w.Alloc();
             try
             {
                 var result = await r.ReadAsync();
                 if (result.IsCancelled)
                 {
                     // read cancelled
                     break;
                 }
                 if (result.IsCompleted && result.Buffer.IsEmpty)
                 {
                     // read end
                     break;
                 }
                 // ReadableBuffer is linked list of System.Memory<T>
                 foreach (var rbuf in result.Buffer)
                 {
                     // allocate buffer for writing
                     wbuf.Ensure(rbuf.Length);
                     // extract write buffer you want to use
                     var span = wbuf.Memory.Span.Slice(0, rbuf.Length);
                     // copy data to write buffer
                     // OutOfRangeException when wbuffer is shorter than read buffer
                     rbuf.CopyTo(span);
                     // change value of write buffer
                     for (int i = 0; i < span.Length; i++)
                     {
                         span[i] = (byte)(span[i] & 0x0f);
                     }
                     // send write buffer to next writer
                     wbuf.Advance(rbuf.Length);
                 }
                 // consume read buffer
                 // must call before next ReadAsync
                 r.Advance(result.Buffer.End);
             }
             catch (Exception e)
             {
                 Console.WriteLine($"{e}");
             }
             // must call FlushAsync before next Alloc
             await wbuf.FlushAsync();
         }
         w.Complete();
     }));
 }
コード例 #15
0
 public static async Task CopyToEndAsync(this Stream stream, IPipeWriter writer)
 {
     try
     {
         await stream.CopyToAsync(writer);
     }
     catch (Exception ex)
     {
         writer.Complete(ex);
         return;
     }
     writer.Complete();
 }
コード例 #16
0
    private static async Task WriteSimpleMessage(IPipeWriter output, string command)
    {
        // keep things simple: using the text protocol guarantees a text-protocol response
        // (in real code we'd use the RESP format, but ... meh)
        await Console.Out.WriteLineAsync($">> sending '{command}'...");

        var buffer = output.Alloc();

        var arr = Encoding.ASCII.GetBytes($"{command}\r\n"); // there's a nice way to do this; I've forgotten

        buffer.Write(arr);
        await buffer.FlushAsync();
    }
コード例 #17
0
 public static async Task CopyToEndAsync(this Stream stream, IPipeWriter writer, CancellationToken cancellationToken = default)
 {
     try
     {
         await stream.CopyToAsync(writer, cancellationToken);
     }
     catch (Exception ex)
     {
         writer.Complete(ex);
         return;
     }
     writer.Complete();
 }
コード例 #18
0
 public Http1OutputProducer(
     IPipeReader outputPipeReader,
     IPipeWriter pipeWriter,
     string connectionId,
     IKestrelTrace log,
     ITimeoutControl timeoutControl)
 {
     _outputPipeReader = outputPipeReader;
     _pipeWriter       = pipeWriter;
     _connectionId     = connectionId;
     _timeoutControl   = timeoutControl;
     _log            = log;
     _flushCompleted = OnFlushCompleted;
 }
コード例 #19
0
ファイル: RedisPing.cs プロジェクト: mgravell/RedisPing
    private static async Task WriteSimpleMessage(IPipeWriter output, string command)
    {
        // keep things simple: using the text protocol guarantees a text-protocol response
        // (in real code we'd use the RESP format, but ... meh)
        var msg = (!ShowDetails && command.StartsWith("AUTH", StringComparison.OrdinalIgnoreCase)) ? "AUTH ****" : command;
        await Console.Out.WriteLineAsync($">> sending '{msg}'...");

        var buffer = output.Alloc();

        buffer.WriteUtf8(command.AsReadOnlySpan());
        buffer.Ensure(CRLF.Length);
        buffer.Write(CRLF);
        buffer.Commit();
        await buffer.FlushAsync();
    }
コード例 #20
0
ファイル: PipeExtensions.cs プロジェクト: zsybupt/corefxlab
        public static Task WriteAsync(this IPipeWriter output, ReadOnlyMemory <byte> source)
        {
            var writeBuffer = output.Alloc();

            writeBuffer.Write(source.Span);

            var awaitable = writeBuffer.FlushAsync();

            if (awaitable.IsCompleted)
            {
                awaitable.GetResult();
                return(_completedTask);
            }

            return(FlushAsyncAwaited(awaitable));
        }
コード例 #21
0
        internal WritableBufferAwaitable WriteAsync(IPipeWriter output)
        {
            var write = output.Alloc();

            if (_buffers != null)
            {
                foreach (var buffer in _buffers)
                {
                    write.Append(buffer.Buffer);
                }
            }
            else
            {
                ApplyMask();
                write.Append(_buffer);
            }
            return(write.FlushAsync());
        }
コード例 #22
0
        private async Task CopyCompletedAsync(IPipeReader input, IPipeWriter output)
        {
            var result = await input.ReadAsync();

            var inputBuffer = result.Buffer;

            while (true)
            {
                try
                {
                    if (inputBuffer.IsEmpty && result.IsCompleted)
                    {
                        return;
                    }

                    var buffer = output.Alloc();
                    foreach (var memory in inputBuffer)
                    {
                        buffer.Write(memory.Span);
                    }
                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }

                var awaiter = input.ReadAsync();

                if (!awaiter.IsCompleted)
                {
                    // No more data
                    break;
                }

                result = await input.ReadAsync();

                inputBuffer = result.Buffer;
            }
        }
コード例 #23
0
        private static async Task CopyCompletedAsync(IPipeReader input, IPipeWriter output)
        {
            var result = await input.ReadAsync();

            var inputBuffer = result.Buffer;

            while (true)
            {
                try
                {
                    if (inputBuffer.IsEmpty && result.IsCompleted)
                    {
                        return;
                    }

                    var buffer = output.Alloc();

                    buffer.Append(inputBuffer);

                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }

                var awaiter = input.ReadAsync();

                if (!awaiter.IsCompleted)
                {
                    // No more data
                    break;
                }

                result = await input.ReadAsync();

                inputBuffer = result.Buffer;
            }
        }
コード例 #24
0
        public static int Main(string[] args)
        {
            Console.WriteLine(string.Join("; ", args));
            int messages = int.Parse(args[1]);

            try
            {
                using (IPipeWriter writer = ParameterParser.GetPipeFromParameters(args[0]))
                {
                    writer.Write(new BuildStartedEventArgs($"Testing", "help"));
                    for (int c = 0; c < messages; c++)
                    {
                        writer.Write(new BuildMessageEventArgs($"Testing {c}", "help", "sender", MessageImportance.Normal));
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return(1);
            }
            return(0);
        }
コード例 #25
0
ファイル: PipeExtensions.cs プロジェクト: WinCPP/corefxlab
 public static Task WriteAsync(this IPipeWriter output, byte[] source)
 {
     return(WriteAsync(output, new ArraySegment <byte>(source)));
 }
コード例 #26
0
 public PipeConnection(IPipeReader reader, IPipeWriter writer)
 {
     Input  = reader;
     Output = writer;
 }
コード例 #27
0
 public PipelineTextOutput(IPipeWriter writer, SymbolTable symbolTable)
 {
     _writer     = writer;
     SymbolTable = symbolTable;
 }
コード例 #28
0
 public static PipelineTextOutput AsTextOutput(this IPipeWriter writer, SymbolTable symbolTable)
 {
     return(new PipelineTextOutput(writer, symbolTable));
 }
コード例 #29
0
 protected RecordHandler(IKeyPair secureConnection, TlsVersion recordVersion, IPipeWriter output)
 {
     _recordVersion = recordVersion;
     _connection    = secureConnection;
     _output        = output;
 }
コード例 #30
0
        private static async void ReadFromSocket(TSocket tsocket, IPipeWriter writer, bool dataMayBeAvailable)
        {
            Exception error = null;

            try
            {
                var  availableBytes = dataMayBeAvailable ? tsocket.Socket.GetAvailableBytes() : 0;
                bool readable0      = true;
                if (availableBytes == 0 &&
                    (readable0 = await Readable(tsocket))) // Readable
                {
                    availableBytes = tsocket.Socket.GetAvailableBytes();
                }
                else if (!readable0)
                {
                    error = new ConnectionAbortedException();
                }
                while (availableBytes != 0)
                {
                    var buffer = writer.Alloc(2048);
                    try
                    {
                        error = Receive(tsocket.Fd, availableBytes, ref buffer);
                        if (error != null)
                        {
                            break;
                        }
                        availableBytes = 0;
                        var flushResult = await buffer.FlushAsync();

                        bool readable = true;
                        if (!flushResult.IsCompleted && // Reader hasn't stopped
                            !flushResult.IsCancelled && // TransportThread hasn't stopped
                            (readable = await Readable(tsocket))) // Readable
                        {
                            availableBytes = tsocket.Socket.GetAvailableBytes();
                        }
                        else if (flushResult.IsCancelled || !readable)
                        {
                            error = new ConnectionAbortedException();
                        }
                    }
                    catch (Exception e)
                    {
                        availableBytes = 0;
                        buffer.Commit();
                        error = e;
                    }
                }
            }
            catch (Exception ex)
            {
                error = ex;
            }
            finally
            {
                // even when error == null, we call Abort
                // this mean receiving FIN causes Abort
                // rationale: https://github.com/aspnet/KestrelHttpServer/issues/1139#issuecomment-251748845
                tsocket.ConnectionContext.Abort(error);
                writer.Complete(error);

                CleanupSocketEnd(tsocket);
            }
        }