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 } }
public static Task WriteAsync(this IPipeWriter output, ArraySegment <byte> source) { var writeBuffer = output.Alloc(); writeBuffer.Write(source); return(FlushAsync(writeBuffer)); }
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(); } }
public static async Task WriteAsync(this IPipeWriter output, Span <byte> source) { var writeBuffer = output.Alloc(); writeBuffer.Write(source); await writeBuffer.FlushAsync(); }
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); } } }
public static Task WriteAsync(this IPipeWriter output, Span <byte> source) { var writeBuffer = output.Alloc(); writeBuffer.Write(source); return(AwaitFlushAsync(writeBuffer)); }
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); } } }
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(); } }
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); }
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); }
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); }
public override void Shutdown() { base.Shutdown(); if (Pipe != null) { Pipe.Dispose(); Pipe = null; } }
public IPipeWriter CreateWriter(IPipeWriter writer, Func <IPipeReader, IPipeWriter, Task> consume) { var pipe = new Pipe(_pool); consume(pipe, writer).ContinueWith(t => { }); return(pipe); }
// 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(); })); }
public static async Task CopyToEndAsync(this Stream stream, IPipeWriter writer) { try { await stream.CopyToAsync(writer); } catch (Exception ex) { writer.Complete(ex); return; } writer.Complete(); }
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(); }
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(); }
public Http1OutputProducer( IPipeReader outputPipeReader, IPipeWriter pipeWriter, string connectionId, IKestrelTrace log, ITimeoutControl timeoutControl) { _outputPipeReader = outputPipeReader; _pipeWriter = pipeWriter; _connectionId = connectionId; _timeoutControl = timeoutControl; _log = log; _flushCompleted = OnFlushCompleted; }
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(); }
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)); }
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()); }
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; } }
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; } }
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); }
public static Task WriteAsync(this IPipeWriter output, byte[] source) { return(WriteAsync(output, new ArraySegment <byte>(source))); }
public PipeConnection(IPipeReader reader, IPipeWriter writer) { Input = reader; Output = writer; }
public PipelineTextOutput(IPipeWriter writer, SymbolTable symbolTable) { _writer = writer; SymbolTable = symbolTable; }
public static PipelineTextOutput AsTextOutput(this IPipeWriter writer, SymbolTable symbolTable) { return(new PipelineTextOutput(writer, symbolTable)); }
protected RecordHandler(IKeyPair secureConnection, TlsVersion recordVersion, IPipeWriter output) { _recordVersion = recordVersion; _connection = secureConnection; _output = output; }
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); } }