#pragma warning restore 1998

        #region UsingAsyncBuildingBlock
        public Task Using(StringBuilder builder)
        {
            return(TaskBlocks.Using(
                       () => AcquireResourceAsync(builder),
                       task => task.Result.WriteAsync(SampleText)));
        }
        protected internal override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (disposed != 0)
            {
                throw new ObjectDisposedException(GetType().ToString());
            }

            Interlocked.Exchange(ref sentRequest, 1);
            wrequest = CreateWebRequest(request);

            Task intermediate;

            if (request.Content != null)
            {
                AddContentHeaders(wrequest, request.Content.Headers);

                intermediate = wrequest.GetRequestStreamAsync()
                               .Then(streamTask => request.Content.CopyToAsync(streamTask.Result).Finally(_ => streamTask.Result.Dispose()));
            }
            else if (HttpMethod.Post.Equals(request.Method) || HttpMethod.Put.Equals(request.Method) || HttpMethod.Delete.Equals(request.Method))
            {
                // Explicitly set this to make sure we're sending a "Content-Length: 0" header.
                // This fixes the issue that's been reported on the forums:
                // http://forums.xamarin.com/discussion/17770/length-required-error-in-http-post-since-latest-release
                wrequest.ContentLength = 0;
                intermediate           = Task.FromResult(default(VoidResult));
            }
            else
            {
                intermediate = Task.FromResult(default(VoidResult));
            }

            HttpWebResponse            wresponse = null;
            Func <Task <IDisposable> > resource  =
                () => Task.FromResult <IDisposable>(cancellationToken.Register(l => ((HttpWebRequest)l).Abort(), wrequest));
            Func <Task <IDisposable>, Task> body =
                _ =>
            {
                return(wrequest.GetResponseAsync().Select(task => wresponse = (HttpWebResponse)task.Result)
                       .Catch <WebException>(
                           (task, we) =>
                {
                    if (we.Status == WebExceptionStatus.ProtocolError)
                    {
                        // HttpClient shouldn't throw exceptions for these errors
                        wresponse = (HttpWebResponse)we.Response;
                    }
                    else if (we.Status != WebExceptionStatus.RequestCanceled)
                    {
                        // propagate the antecedent
                        return task;
                    }

                    return Task.FromResult(default(VoidResult));
                })
                       .Then(
                           task =>
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return Task.FromCanceled <HttpResponseMessage>(cancellationToken);
                    }
                    else
                    {
                        return Task.FromResult(default(VoidResult));
                    }
                }));
            };

            return(intermediate
                   .Then(_ => TaskBlocks.Using(resource, body))
                   .Select(_ => CreateResponseMessage(wresponse, request, cancellationToken)));
        }
Ejemplo n.º 3
0
        protected internal override Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            // RFC 2046
            //
            // The Content-Type field for multipart entities requires one parameter,
            // "boundary". The boundary delimiter line is then defined as a line
            // consisting entirely of two hyphen characters ("-", decimal value 45)
            // followed by the boundary parameter value from the Content-Type header
            // field, optional linear whitespace, and a terminating CRLF.
            //

            byte[] buffer;
            var    sb = new StringBuilder();

            sb.Append('-').Append('-');
            sb.Append(boundary);
            sb.Append('\r').Append('\n');

            int         i         = 0;
            Func <bool> condition = () => i < nested_content.Count;
            Func <Task> body      =
                () =>
            {
                var c = nested_content[i];

                foreach (var h in c.Headers)
                {
                    sb.Append(h.Key);
                    sb.Append(':').Append(' ');
                    foreach (var v in h.Value)
                    {
                        sb.Append(v);
                    }
                    sb.Append('\r').Append('\n');
                }
                sb.Append('\r').Append('\n');

                buffer    = Encoding.ASCII.GetBytes(sb.ToString());
                sb.Length = 0;

                return(stream.WriteAsync(buffer, 0, buffer.Length)
                       .Then(_ => c.SerializeToStreamAsync(stream, context))
                       .Select(
                           _ =>
                {
                    if (i != nested_content.Count - 1)
                    {
                        sb.Append('\r').Append('\n');
                        sb.Append('-').Append('-');
                        sb.Append(boundary);
                        sb.Append('\r').Append('\n');
                    }

                    i++;
                }));
            };

            Func <Task, Task> continuationFunction =
                task =>
            {
                sb.Append('\r').Append('\n');
                sb.Append('-').Append('-');
                sb.Append(boundary);
                sb.Append('-').Append('-');
                sb.Append('\r').Append('\n');

                buffer = Encoding.ASCII.GetBytes(sb.ToString());
                return(stream.WriteAsync(buffer, 0, buffer.Length));
            };

            return(TaskBlocks.While(condition, body)
                   .Then(continuationFunction));
        }
#pragma warning restore 1998

        #region UsingWithResultAsyncBuildingBlock
        public Task <string> UsingWithResult()
        {
            return(TaskBlocks.Using(
                       () => AcquireResourceAsync(),
                       task => task.Result.ReadToEndAsync()));
        }