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) { #if NET46 return(await c.ReadAsByteArrayAsync().ConfigureAwait(false)); #else Headers.HttpContentHeaders headers = c.Headers; using (Stream responseStream = c.TryReadAsStream() ?? 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(); } } } #endif } // No content to return. return(Array.Empty <byte>()); } }
private async Task <string> GetStringAsyncCore(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) { #if NET46 return(await c.ReadAsStringAsync().ConfigureAwait(false)); #else Headers.HttpContentHeaders headers = c.Headers; // Since the underlying byte[] will never be exposed, we use an ArrayPool-backed // stream to which we copy all of the data from the response. using (Stream responseStream = c.TryReadAsStream() ?? await c.ReadAsStreamAsync().ConfigureAwait(false)) using (var buffer = new HttpContent.LimitArrayPoolWriteStream(_maxResponseContentBufferSize, (int)headers.ContentLength.GetValueOrDefault())) { await responseStream.CopyToAsync(buffer).ConfigureAwait(false); if (buffer.Length > 0) { // Decode and return the data from the buffer. return(HttpContent.ReadBufferAsString(buffer.GetBuffer(), headers)); } } #endif } // No content to return. return(string.Empty); } }