private async Task<byte[]> GetByteArrayAsyncCore(Task<HttpResponseMessage> getTask)
{
// Wait for the response message.
using (HttpResponseMessage responseMessage = await getTask.ConfigureAwait(false))
{
// Make sure it completed successfully.
responseMessage.EnsureSuccessStatusCode();
// Get the response content.
HttpContent c = responseMessage.Content;
if (c != null)
{
HttpContentHeaders headers = c.Headers;
using (Stream responseStream = await c.ReadAsStreamAsync().ConfigureAwait(false))
{
long? contentLength = headers.ContentLength;
Stream buffer; // declared here to share the state machine field across both if/else branches
if (contentLength.HasValue)
{
// If we got a content length, then we assume that it's correct and create a MemoryStream
// to which the content will be transferred. That way, assuming we actually get the exact
// amount we were expecting, we can simply return the MemoryStream's underlying buffer.
buffer = new HttpContent.LimitMemoryStream(_maxResponseContentBufferSize, (int)contentLength.GetValueOrDefault());
await responseStream.CopyToAsync(buffer).ConfigureAwait(false);
if (buffer.Length > 0)
{
return ((HttpContent.LimitMemoryStream)buffer).GetSizedBuffer();
}
}
else
{
// If we didn't get a content length, then we assume we're going to have to grow
// the buffer potentially several times and that it's unlikely the underlying buffer
// at the end will be the exact size needed, in which case it's more beneficial to use
// ArrayPool buffers and copy out to a new array at the end.
buffer = new HttpContent.LimitArrayPoolWriteStream(_maxResponseContentBufferSize);
try
{
await responseStream.CopyToAsync(buffer).ConfigureAwait(false);
if (buffer.Length > 0)
{
return ((HttpContent.LimitArrayPoolWriteStream)buffer).ToArray();
}
}
finally { buffer.Dispose(); }
}
}
}
// No content to return.
return Array.Empty<byte>();
}
}