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); }