private async Task copyBodyAsync(bool isRequest, bool useOriginalHeaderValues, HttpWriter writer, TransformationMode transformation, Action <byte[], int, int> onCopy, CancellationToken cancellationToken)
        {
            var stream = getStreamReader(isRequest);

            var requestResponse = isRequest ? (RequestResponseBase)WebSession.Request : WebSession.Response;

            bool isChunked     = useOriginalHeaderValues? requestResponse.OriginalIsChunked : requestResponse.IsChunked;
            long contentLength = useOriginalHeaderValues ? requestResponse.OriginalContentLength : requestResponse.ContentLength;

            if (transformation == TransformationMode.None)
            {
                await writer.CopyBodyAsync(stream, isChunked, contentLength, onCopy, cancellationToken);

                return;
            }

            LimitedStream limitedStream;
            Stream        decompressStream = null;

            string contentEncoding = useOriginalHeaderValues ? requestResponse.OriginalContentEncoding : requestResponse.ContentEncoding;

            Stream s = limitedStream = new LimitedStream(stream, bufferPool, isChunked, contentLength);

            if (transformation == TransformationMode.Uncompress && contentEncoding != null)
            {
                s = decompressStream = DecompressionFactory.Create(contentEncoding, s);
            }

            try
            {
                using (var bufStream = new CustomBufferedStream(s, bufferPool, bufferSize, true))
                {
                    await writer.CopyBodyAsync(bufStream, false, -1, onCopy, cancellationToken);
                }
            }
            finally
            {
                decompressStream?.Dispose();

                await limitedStream.Finish();

                limitedStream.Dispose();
            }
        }