Ejemplo n.º 1
0
    /// <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;
            }
        }
    }
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 3
0
        /// <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;
                }
            }
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
    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);
        }
    }
Ejemplo n.º 6
0
    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());
                }
            }
        }
Ejemplo n.º 9
0
        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());
                    }
                }
            }
        }
Ejemplo n.º 10
0
        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);
        }