public override void ReceivedResponse(NSUrlConnection connection, NSUrlResponse response) { try { responseMessage.RequestMessage.RequestUri = new Uri(response.Url.ToString()); //At least attempt to get the url right if we redirected var httpResponse = response as NSHttpUrlResponse; if (httpResponse != null) { stream = new ByteArrayListStream(); content = new CancellableStreamContent(stream, () => { isComplete = true; stream.SetException(new OperationCanceledException()); }); responseMessage.StatusCode = (HttpStatusCode)httpResponse.StatusCode; responseMessage.Content = content; foreach (var header in httpResponse.AllHeaderFields) { if (header.Key != null && header.Value != null) { responseMessage.Headers.TryAddWithoutValidation(header.Key.ToString(), header.Value.ToString()); responseMessage.Content.Headers.TryAddWithoutValidation(header.Key.ToString(), header.Value.ToString()); } } } } finally { waitEvent.Set(); } }
public override void DidReceiveResponse(NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action <NSUrlSessionResponseDisposition> completionHandler) { var data = getResponseForTask(dataTask); try { if (data.CancellationToken.IsCancellationRequested) { dataTask.Cancel(); } var resp = (NSHttpUrlResponse)response; var req = data.Request; if (This.throwOnCaptiveNetwork && req.RequestUri.Host != resp.Url.Host) { throw new CaptiveNetworkException(req.RequestUri, new Uri(resp.Url.ToString())); } var content = new CancellableStreamContent(data.ResponseBody, () => { if (!data.IsCompleted) { dataTask.Cancel(); } data.IsCompleted = true; data.ResponseBody.SetException(new OperationCanceledException()); }); content.Progress = data.Progress; // NB: The double cast is because of a Xamarin compiler bug int status = (int)resp.StatusCode; var ret = new HttpResponseMessage((HttpStatusCode)status) { Content = content, RequestMessage = data.Request, }; foreach (var v in resp.AllHeaderFields) { // NB: Cocoa trolling us so hard by giving us back dummy // dictionary entries if (v.Key == null || v.Value == null) { continue; } ret.Headers.TryAddWithoutValidation(v.Key.ToString(), v.Value.ToString()); ret.Content.Headers.TryAddWithoutValidation(v.Key.ToString(), v.Value.ToString()); } // NB: The awaiting code can synchronously call read, which will block, and we'll // never get a didReceiveData, because we have not returned from DidReceiveResponse. Task.Run(() => { data.FutureResponse.TrySetResult(ret); }); } catch (Exception ex) { data.FutureResponse.TrySetException(ex); } completionHandler(NSUrlSessionResponseDisposition.Allow); }
public override void DidReceiveResponse(NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action<NSUrlSessionResponseDisposition> completionHandler) { var data = getResponseForTask(dataTask); try { if (data.CancellationToken.IsCancellationRequested) { dataTask.Cancel(); } var resp = (NSHttpUrlResponse)response; var req = data.Request; if (This.throwOnCaptiveNetwork && req.RequestUri.Host != resp.Url.Host) { throw new CaptiveNetworkException(req.RequestUri, new Uri(resp.Url.ToString())); } var content = new CancellableStreamContent(data.ResponseBody, () => { if (!data.IsCompleted) { dataTask.Cancel(); } data.IsCompleted = true; data.ResponseBody.SetException(new OperationCanceledException()); }); content.Progress = data.Progress; // NB: The double cast is because of a Xamarin compiler bug int status = (int)resp.StatusCode; var ret = new HttpResponseMessage((HttpStatusCode)status) { Content = content, RequestMessage = data.Request, }; ret.RequestMessage.RequestUri = new Uri(resp.Url.AbsoluteString); foreach(var v in resp.AllHeaderFields) { // NB: Cocoa trolling us so hard by giving us back dummy // dictionary entries if (v.Key == null || v.Value == null) continue; ret.Headers.TryAddWithoutValidation(v.Key.ToString(), v.Value.ToString()); ret.Content.Headers.TryAddWithoutValidation(v.Key.ToString(), v.Value.ToString()); } data.FutureResponse.TrySetResult(ret); } catch (Exception ex) { data.FutureResponse.TrySetException(ex); } completionHandler(NSUrlSessionResponseDisposition.Allow); }