Ejemplo n.º 1
0
        public Task <Stream> ReadAsStreamAsync()
        {
            CheckDisposed();

            TaskCompletionSource <Stream> tcs = new TaskCompletionSource <Stream>();

            if (contentReadStream == null && IsBuffered)
            {
                // We cast bufferedContent.Length to 'int': The framework doesn't support arrays > int.MaxValue,
                // so the length will always be in the 'int' range.
                contentReadStream = new MemoryStream(bufferedContent.GetBuffer(), 0,
                                                     (int)bufferedContent.Length, false, false);
            }

            if (contentReadStream != null)
            {
                tcs.TrySetResult(contentReadStream);
                return(tcs.Task);
            }

            CreateContentReadStreamAsync().ContinueWithStandard(task =>
            {
                if (!HttpUtilities.HandleFaultsAndCancelation(task, tcs))
                {
                    contentReadStream = task.Result;
                    tcs.TrySetResult(contentReadStream);
                }
            });

            return(tcs.Task);
        }
Ejemplo n.º 2
0
        // Returns true if the task was faulted or canceled and sets tcs accordingly. Non-success status codes count as
        // faults in cases where the HttpResponseMessage object will not be returned to the developer.
        private static bool HandleRequestFaultsAndCancelation <T>(Task <HttpResponseMessage> task,
                                                                  TaskCompletionSource <T> tcs)
        {
            if (HttpUtilities.HandleFaultsAndCancelation(task, tcs))
            {
                return(true);
            }

            HttpResponseMessage response = task.Result;

            if (!response.IsSuccessStatusCode)
            {
                if (response.Content != null)
                {
                    response.Content.Dispose();
                }

                tcs.TrySetException(new HttpRequestException(
                                        string.Format(System.Globalization.CultureInfo.InvariantCulture,
                                                      SR.net_http_message_not_success_statuscode, (int)response.StatusCode,
                                                      response.ReasonPhrase)));
                return(true);
            }
            return(false);
        }
Ejemplo n.º 3
0
        public Task <Stream> ReadAsStreamAsync()
        {
            CheckDisposed();

            TaskCompletionSource <Stream> tcs = new TaskCompletionSource <Stream>();

            if (_contentReadStream == null && IsBuffered)
            {
                byte[] data = this.GetDataBuffer(_bufferedContent);

                // We can cast bufferedContent.Length to 'int' since the length will always be in the 'int' range
                // The .NET Framework doesn't support array lengths > int.MaxValue.
                Debug.Assert(_bufferedContent.Length <= (long)int.MaxValue);
                _contentReadStream = new MemoryStream(data, 0,
                                                      (int)_bufferedContent.Length, false);
            }

            if (_contentReadStream != null)
            {
                tcs.TrySetResult(_contentReadStream);
                return(tcs.Task);
            }

            CreateContentReadStreamAsync().ContinueWithStandard(task =>
            {
                if (!HttpUtilities.HandleFaultsAndCancelation(task, tcs))
                {
                    _contentReadStream = task.Result;
                    tcs.TrySetResult(_contentReadStream);
                }
            });

            return(tcs.Task);
        }
Ejemplo n.º 4
0
        public Task <byte[]> ReadAsByteArrayAsync()
        {
            CheckDisposed();

            TaskCompletionSource <byte[]> tcs = new TaskCompletionSource <byte[]>();

            LoadIntoBufferAsync().ContinueWithStandard(task =>
            {
                if (!HttpUtilities.HandleFaultsAndCancelation(task, tcs))
                {
                    tcs.TrySetResult(bufferedContent.ToArray());
                }
            });

            return(tcs.Task);
        }
Ejemplo n.º 5
0
        protected virtual Task <Stream> CreateContentReadStreamAsync()
        {
            TaskCompletionSource <Stream> tcs = new TaskCompletionSource <Stream>();

            // By default just buffer the content to a memory stream. Derived classes can override this behavior
            // if there is a better way to retrieve the content as stream (e.g. byte array/string use a more efficient
            // way, like wrapping a read-only MemoryStream around the bytes/string)
            LoadIntoBufferAsync().ContinueWithStandard(task =>
            {
                if (!HttpUtilities.HandleFaultsAndCancelation(task, tcs))
                {
                    tcs.TrySetResult(bufferedContent);
                }
            });

            return(tcs.Task);
        }
Ejemplo n.º 6
0
        private Task <Stream> ReadAsStreamAsyncCore()
        {
            TaskCompletionSource <Stream> tcs = new TaskCompletionSource <Stream>(this);

            CreateContentReadStreamAsync().ContinueWithStandard(tcs, (task, state) =>
            {
                var innerTcs  = (TaskCompletionSource <Stream>)state;
                var innerThis = (HttpContent)innerTcs.Task.AsyncState;
                if (!HttpUtilities.HandleFaultsAndCancelation(task, innerTcs))
                {
                    innerThis._contentReadStream = task.Result;
                    innerTcs.TrySetResult(innerThis._contentReadStream);
                }
            });

            return(tcs.Task);
        }
Ejemplo n.º 7
0
        public Task <byte[]> ReadAsByteArrayAsync()
        {
            CheckDisposed();

            var tcs = new TaskCompletionSource <byte[]>(this);

            LoadIntoBufferAsync().ContinueWithStandard(tcs, (task, state) =>
            {
                var innerTcs  = (TaskCompletionSource <byte[]>)state;
                var innerThis = (HttpContent)innerTcs.Task.AsyncState;
                if (!HttpUtilities.HandleFaultsAndCancelation(task, innerTcs))
                {
                    innerTcs.TrySetResult(innerThis._bufferedContent.ToArray());
                }
            });

            return(tcs.Task);
        }
Ejemplo n.º 8
0
        private Task <T> GetContentAsync <T>(Uri requestUri, HttpCompletionOption completionOption, T defaultValue,
                                             Func <HttpContent, Task <T> > readAs)
        {
            TaskCompletionSource <T> tcs = new TaskCompletionSource <T>();

            GetAsync(requestUri, completionOption).ContinueWithStandard(requestTask =>
            {
                if (HandleRequestFaultsAndCancelation(requestTask, tcs))
                {
                    return;
                }
                HttpResponseMessage response = requestTask.Result;
                if (response.Content == null)
                {
                    tcs.TrySetResult(defaultValue);
                    return;
                }

                try
                {
                    readAs(response.Content).ContinueWithStandard(contentTask =>
                    {
                        if (!HttpUtilities.HandleFaultsAndCancelation(contentTask, tcs))
                        {
                            tcs.TrySetResult(contentTask.Result);
                        }
                    });
                }
                catch (Exception ex)
                {
                    tcs.TrySetException(ex);
                }
            });

            return(tcs.Task);
        }
Ejemplo n.º 9
0
        public Task <string> ReadAsStringAsync()
        {
            CheckDisposed();

            var tcs = new TaskCompletionSource <string>(this);

            LoadIntoBufferAsync().ContinueWithStandard(tcs, (task, state) =>
            {
                var innerTcs  = (TaskCompletionSource <string>)state;
                var innerThis = (HttpContent)innerTcs.Task.AsyncState;
                if (HttpUtilities.HandleFaultsAndCancelation(task, innerTcs))
                {
                    return;
                }

                if (innerThis._bufferedContent.Length == 0)
                {
                    innerTcs.TrySetResult(string.Empty);
                    return;
                }

                // We don't validate the Content-Encoding header: If the content was encoded, it's the caller's
                // responsibility to make sure to only call ReadAsString() on already decoded content. E.g. if the
                // Content-Encoding is 'gzip' the user should set HttpClientHandler.AutomaticDecompression to get a
                // decoded response stream.

                Encoding encoding = null;
                int bomLength     = -1;

                byte[] data = innerThis.GetDataBuffer(innerThis._bufferedContent);

                int dataLength = (int)innerThis._bufferedContent.Length; // Data is the raw buffer, it may not be full.

                // If we do have encoding information in the 'Content-Type' header, use that information to convert
                // the content to a string.
                if ((innerThis.Headers.ContentType != null) && (innerThis.Headers.ContentType.CharSet != null))
                {
                    try
                    {
                        encoding = Encoding.GetEncoding(innerThis.Headers.ContentType.CharSet);
                    }
                    catch (ArgumentException e)
                    {
                        innerTcs.TrySetException(new InvalidOperationException(SR.net_http_content_invalid_charset, e));
                        return;
                    }
                }

                // If no content encoding is listed in the ContentType HTTP header, or no Content-Type header present,
                // then check for a byte-order-mark (BOM) in the data to figure out the encoding.
                if (encoding == null)
                {
                    byte[] preamble;
                    foreach (Encoding testEncoding in s_encodingsWithBom)
                    {
                        preamble = testEncoding.GetPreamble();
                        if (ByteArrayHasPrefix(data, dataLength, preamble))
                        {
                            encoding  = testEncoding;
                            bomLength = preamble.Length;
                            break;
                        }
                    }
                }

                // Use the default encoding if we couldn't detect one.
                encoding = encoding ?? DefaultStringEncoding;

                // BOM characters may be present even if a charset was specified.
                if (bomLength == -1)
                {
                    byte[] preamble = encoding.GetPreamble();
                    if (ByteArrayHasPrefix(data, dataLength, preamble))
                    {
                        bomLength = preamble.Length;
                    }
                    else
                    {
                        bomLength = 0;
                    }
                }

                try
                {
                    // Drop the BOM when decoding the data.
                    string result = encoding.GetString(data, bomLength, dataLength - bomLength);
                    innerTcs.TrySetResult(result);
                }
                catch (Exception ex)
                {
                    innerTcs.TrySetException(ex);
                }
            });

            return(tcs.Task);
        }