示例#1
0
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if ((this.Credentials != null) && (this.Credentials.GetCredential(request.RequestUri, "Digest") != null))
            {
                client.SetAuthenticator(new DigestAuthenticator(this.Credentials));
            }

            var java_uri = request.RequestUri.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped);
            var url      = new Java.Net.URL(java_uri);

            var body = default(RequestBody);

            if (request.Content != null)
            {
                var bytes = await request.Content.ReadAsByteArrayAsync().ConfigureAwait(false);

                var contentType = "text/plain";
                if (request.Content.Headers.ContentType != null)
                {
                    contentType = String.Join(" ", request.Content.Headers.GetValues("Content-Type"));
                }
                body = RequestBody.Create(MediaType.Parse(contentType), bytes);
            }

            var builder = new Request.Builder()
                          .Method(request.Method.Method.ToUpperInvariant(), body)
                          .Url(url);

            if (DisableCaching)
            {
                builder.CacheControl(noCacheCacheControl);
            }

            var keyValuePairs = request.Headers
                                .Union(request.Content != null ?
                                       (IEnumerable <KeyValuePair <string, IEnumerable <string> > >)request.Content.Headers :
                                       Enumerable.Empty <KeyValuePair <string, IEnumerable <string> > >());

            foreach (var kvp in keyValuePairs)
            {
                builder.AddHeader(kvp.Key, String.Join(getHeaderSeparator(kvp.Key), kvp.Value));
            }

            cancellationToken.ThrowIfCancellationRequested();

            var rq   = builder.Build();
            var call = client.NewCall(rq);

            // NB: Even closing a socket must be done off the UI thread. Cray!
            cancellationToken.Register(() => Task.Run(() => call.Cancel()));

            var resp = default(Response);

            try {
                resp = await call.EnqueueAsync().ConfigureAwait(false);

                var newReq = resp.Request();
                var newUri = newReq == null ? null : newReq.Uri();
                request.RequestUri = new Uri(newUri.ToString());
                if (throwOnCaptiveNetwork && newUri != null)
                {
                    if (url.Host != newUri.Host)
                    {
                        throw new CaptiveNetworkException(new Uri(java_uri), new Uri(newUri.ToString()));
                    }
                }
            } catch (IOException ex) {
                if (ex.Message.ToLowerInvariant().Contains("canceled"))
                {
                    throw new OperationCanceledException();
                }

                throw;
            }

            var respBody = resp.Body();

            cancellationToken.ThrowIfCancellationRequested();

            var ret = new HttpResponseMessage((HttpStatusCode)resp.Code());

            ret.RequestMessage = request;
            ret.ReasonPhrase   = resp.Message();
            if (respBody != null)
            {
                var content = new ProgressStreamContent(respBody.ByteStream(), CancellationToken.None);
                content.Progress = getAndRemoveCallbackFromRegister(request);
                ret.Content      = content;
            }
            else
            {
                ret.Content = new ByteArrayContent(new byte[0]);
            }

            var respHeaders = resp.Headers();

            foreach (var k in respHeaders.Names())
            {
                ret.Headers.TryAddWithoutValidation(k, respHeaders.Get(k));
                ret.Content.Headers.TryAddWithoutValidation(k, respHeaders.Get(k));
            }

            return(ret);
        }