/// <summary> /// Waits until a whole HTTP/1 header, terminated by \r\n\r\n was received. /// This may only be called once at the beginning of the stream. /// If the header was found it can be accessed with HeaderBytes. /// Then it must be either consumed or marked as unread. /// </summary> public async Task WaitForHttpHeader() { while (true) { var res = await stream.ReadAsync( new ArraySegment <byte>(httpBuffer, httpBufferOffset, httpBuffer.Length - httpBufferOffset)); if (res.EndOfStream) { throw new System.IO.EndOfStreamException(); } httpBufferOffset += res.BytesRead; // Check for end of headers in the received data var str = Encoding.ASCII.GetString(httpBuffer, 0, httpBufferOffset); var endOfHeaderIndex = str.IndexOf("\r\n\r\n"); if (endOfHeaderIndex == -1) { // Header end not yet found if (httpBufferOffset == httpBuffer.Length) { httpBuffer = null; throw new Exception("No HTTP header received"); } // else read more bytes by looping around } else { httpHeaderLength = endOfHeaderIndex + 4; return; } } }
public ValueTask <StreamReadResult> ReadAsync(ArraySegment <byte> buffer) { if (_completeRemains.Count != 0) { // Return leftover bytes from upgrade request var toCopy = Math.Min(_completeRemains.Count, buffer.Count); Array.Copy( _completeRemains.Array, _completeRemains.Offset, buffer.Array, buffer.Offset, toCopy); var newOffset = _completeRemains.Offset + toCopy; var newCount = _completeRemains.Count - toCopy; if (newCount != 0) { _completeRemains = new ArraySegment <byte>(_completeRemains.Array, newOffset, newCount); } else { _completeRemains = new ArraySegment <byte>(); _httpBuffer = null; } return(new ValueTask <StreamReadResult>( new StreamReadResult { BytesRead = toCopy, EndOfStream = false })); } return(_stream.ReadAsync(buffer)); }
/// <summary> /// 等待直到收到由\r\n\r\n终止的整个HTTP/1头。 /// </summary> /// <returns></returns> public async Task WaitForHttpHeader() { while (true) { var res = await stream.ReadAsync( new ArraySegment <byte>(httpBuffer, httpBufferOffset, httpBuffer.Length - httpBufferOffset)); if (res.EndOfStream) { throw new System.IO.EndOfStreamException(); } httpBufferOffset += res.BytesRead; var str = Encoding.ASCII.GetString(httpBuffer, 0, httpBufferOffset); var endOfHeaderIndex = str.IndexOf("\r\n\r\n"); if (endOfHeaderIndex == -1) { if (httpBufferOffset == httpBuffer.Length) { httpBuffer = null; throw new Exception("未接收到HTTP头"); } } else { httpHeaderLength = endOfHeaderIndex + 4; return; } } }
/// <summary> /// Tries to read exactly the given amount of data from a stream. /// The method will only return if all data was read, the stream /// closed or the an error happened. /// If the input is a 0 byte buffer the method will always succeed, /// even if the underlying stream was already closed. /// </summary> /// <param name="stream">The stream to read data from</param> /// <param name="buffer">The destination buffer</param> /// <returns>Awaitable task object</returns> public async static ValueTask <DoneHandle> ReadAll( this IReadableByteStream stream, ArraySegment <byte> buffer) { var array = buffer.Array; var offset = buffer.Offset; var count = buffer.Count; // Remark: This will not perform actual 0 byte reads to the underlying // stream, which means it won't detect closed streams on 0 byte reads. while (count != 0) { var segment = new ArraySegment <byte>(array, offset, count); var res = await stream.ReadAsync(segment); if (res.EndOfStream) { throw new System.IO.EndOfStreamException(); } offset += res.BytesRead; count -= res.BytesRead; } return(DoneHandle.Instance); }
public async static Task CopyToAsync( this IReadableByteStream stream, IWriteableByteStream dest) { var buf = Buffers.Pool.Rent(64 * 1024); var bytesRead = 0; try { while (true) { var res = await stream.ReadAsync(new ArraySegment <byte>(buf)); if (res.BytesRead != 0) { await dest.WriteAsync(new ArraySegment <byte>(buf, 0, res.BytesRead)); bytesRead += res.BytesRead; } if (res.EndOfStream) { return; } } } finally { Buffers.Pool.Return(buf); } }
public async static Task DrainAsync(this IReadableByteStream stream) { var buf = Buffers.Pool.Rent(8 * 1024); var bytesRead = 0; try { while (true) { var res = await stream.ReadAsync(new ArraySegment <byte>(buf)); if (res.BytesRead != 0) { bytesRead += res.BytesRead; } if (res.EndOfStream) { return; } } } finally { Buffers.Pool.Return(buf); } }
public static async Task <StreamReadResult> ReadWithTimeout( this IReadableByteStream stream, ArraySegment <byte> buf) { var readTask = stream.ReadAsync(buf).AsTask(); var timeoutTask = Task.Delay(ReadTimeout); var combined = Task.WhenAny(new Task[] { readTask, timeoutTask }); var done = await combined; if (done == readTask) { return(readTask.Result); } throw new TimeoutException(); }
public static async Task <byte[]> ReadAllToArray( this IReadableByteStream stream) { var totalBuf = new MemoryStream(); var buf = new byte[16 * 1024]; while (true) { var res = await stream.ReadAsync(new ArraySegment <byte>(buf)); if (res.BytesRead > 0) { totalBuf.Write(buf, 0, res.BytesRead); } if (res.EndOfStream) { return(totalBuf.ToArray()); } } }
static async Task <byte[]> ReadAllToArray( this IReadableByteStream stream) { var readBuffer = Buffers.Pool.Rent(ReadBufferSize); using (var memoryStream = new MemoryStream()) { while (true) { var streamReadResult = await stream.ReadAsync(new ArraySegment <byte>(readBuffer)); if (streamReadResult.BytesRead > 0) { memoryStream.Write(readBuffer, 0, streamReadResult.BytesRead); } if (streamReadResult.EndOfStream) { return(memoryStream.ToArray()); } } } }
public async static ValueTask <DoneHandle> ReadAll( this IReadableByteStream stream, ArraySegment <byte> buffer) { var array = buffer.Array; var offset = buffer.Offset; var count = buffer.Count; while (count != 0) { var segment = new ArraySegment <byte>(array, offset, count); var res = await stream.ReadAsync(segment); if (res.EndOfStream) { throw new System.IO.EndOfStreamException(); } offset += res.BytesRead; count -= res.BytesRead; } return(DoneHandle.Instance); }