public async Task Execute(PipeReader reader, PipeWriter 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; var buffer = inputBuffer.First; if (buffer.Length > 0) { unsafe { var handle = buffer.Retain(pin: true); handles.Add(handle); _inflater.SetInput((IntPtr)handle.Pointer, buffer.Length); var wbuffer = writerBuffer.GetMemory(); handle = wbuffer.Retain(pin: true); handles.Add(handle); int written = _inflater.Inflate((IntPtr)handle.Pointer, wbuffer.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(); } }
private async Task CopyCompletedAsync(PipeReader input, PipeWriter output) { var result = await input.ReadAsync(); var inputBuffer = result.Buffer; while (true) { try { if (inputBuffer.IsEmpty && result.IsCompleted) { return; } var buffer = output; 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; } }
protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context) { long remaining = ContentLength; while (remaining > 0) { var result = await _output.ReadAsync(); var inputBuffer = result.Buffer; var fin = result.IsCompleted; var consumed = inputBuffer.Start; try { if (inputBuffer.IsEmpty && fin) { return; } var data = inputBuffer.Slice(0, remaining); foreach (var memory in data) { await stream.WriteAsync(memory); } consumed = data.End; remaining -= data.Length; } finally { _output.Advance(consumed); } } }
public async Task ProcessAllRequests() { Reset(); while (true) { var result = await _input.ReadAsync(); var buffer = result.Buffer; var consumed = buffer.Start; var examined = buffer.Start; try { if (buffer.IsEmpty && result.IsCompleted) { // We're done with this connection return; } var parserResult = _parser.ParseRequest(buffer, out consumed, out examined); switch (parserResult) { case HttpRequestParser.ParseResult.Incomplete: if (result.IsCompleted) { // Didn't get the whole request and the connection ended throw new EndOfStreamException(); } // Need more data continue; case HttpRequestParser.ParseResult.Complete: // Done break; case HttpRequestParser.ParseResult.BadRequest: // TODO: Don't throw here; throw new Exception(); default: break; } } catch (Exception) { StatusCode = 400; await EndResponse(); return; } finally { _input.Advance(consumed, examined); } 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(); } }
public async Task Execute(PipeReader reader, PipeWriter 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; var buffer = inputBuffer.First; unsafe { var handle = buffer.Retain(pin: true); handles.Add(handle); _deflater.SetInput((IntPtr)handle.Pointer, buffer.Length); } while (!_deflater.NeedsInput()) { unsafe { var wbuffer = writerBuffer.GetMemory(); var handle = wbuffer.Retain(pin: true); handles.Add(handle); int written = _deflater.ReadDeflateOutput((IntPtr)handle.Pointer, wbuffer.Length); writerBuffer.Advance(written); } } var consumed = buffer.Length - _deflater.AvailableInput; inputBuffer = inputBuffer.Slice(0, consumed); reader.Advance(inputBuffer.End); await writerBuffer.FlushAsync(); } bool flushed = false; do { // Need to do more stuff here var writerBuffer = writer; unsafe { var memory = writerBuffer.GetMemory(); var handle = memory.Retain(pin: true); handles.Add(handle); flushed = _deflater.Flush((IntPtr)handle.Pointer, memory.Length, out int compressedBytes); writerBuffer.Advance(compressedBytes); } await writerBuffer.FlushAsync(); }while (flushed); bool finished = false; do { // Need to do more stuff here var writerBuffer = writer; unsafe { var memory = writerBuffer.GetMemory(); var handle = memory.Retain(pin: true); handles.Add(handle); finished = _deflater.Finish((IntPtr)handle.Pointer, memory.Length, out int compressedBytes); writerBuffer.Advance(compressedBytes); } await writerBuffer.FlushAsync(); }while (!finished); reader.Complete(); writer.Complete(); _deflater.Dispose(); foreach (var handle in handles) { handle.Dispose(); } }