public override void DidFinishDownloading(NSUrlSession session, NSUrlSessionDownloadTask downloadTask, NSUrl location) { if (!downloadTasks.ContainsKey(downloadTask.TaskIdentifier)) return; var cachedTaskInfo = downloadTasks[downloadTask.TaskIdentifier]; try { OnFileDownloadProgress(cachedTaskInfo.Index, 100f); var tmpLocation = location.Path; var dirName = Path.GetDirectoryName(cachedTaskInfo.DestinationDiskPath); if (!Directory.Exists(dirName)) Directory.CreateDirectory(dirName); if (File.Exists(cachedTaskInfo.DestinationDiskPath)) File.Delete(cachedTaskInfo.DestinationDiskPath); File.Move(tmpLocation, cachedTaskInfo.DestinationDiskPath); OnFileDownloadedSuccessfully(cachedTaskInfo.Index, cachedTaskInfo.DestinationDiskPath); CleanUpCachedTask(cachedTaskInfo); } catch (Exception exception) { OnError(cachedTaskInfo, new NSError(new NSString(exception.Message), 1)); } }
public override void ViewDidLoad() { base.ViewDidLoad (); this.View.BackgroundColor = UIColor.LightGray; if (session == null) { session = CreateBackgroundSession (); } btnStart = new UIButton (UIButtonType.RoundedRect); btnStart.SetTitle ("Start", UIControlState.Normal); btnStart.Frame = new RectangleF (100, 50, 100, 50); this.View.AddSubview (btnStart); float width = this.View.Bounds.Width - 100; prgView = new UIProgressView(new RectangleF(50,125,width,35)); this.View.AddSubview (prgView); imgView = new UIImageView (new RectangleF (50, 200, width, width)); this.View.AddSubview (imgView); prgView.Progress = 0; imgView.Hidden = false; prgView.Hidden = true; btnStart.TouchUpInside += Start; }
public override void DidFinishEventsForBackgroundSession(NSUrlSession session) { if (HttpService.BackgroundSessionCompletionHandler != null) { Action handler = HttpService.BackgroundSessionCompletionHandler; HttpService.BackgroundSessionCompletionHandler = null; handler.Invoke(); } }
public NativeMessageHandler(bool throwOnCaptiveNetwork, bool customSSLVerification) { session = NSUrlSession.FromConfiguration( NSUrlSessionConfiguration.DefaultSessionConfiguration, new DataTaskDelegate(this), null); this.throwOnCaptiveNetwork = throwOnCaptiveNetwork; this.customSSLVerification = customSSLVerification; }
public override void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error) { if (error != null) { TaskDescription description = JsonParser.ParseTaskDescription(task.TaskDescription).Result; OnDownloadCompleted("", task.TaskDescription ?? "", error.LocalizedDescription); } }
public override void DidCompleteWithError (NSUrlSession session, NSUrlSessionTask task, NSError error) { if (error == null) { return; } Console.WriteLine ("DidCompleteWithError - Task: {0}, Error: {1}", task.TaskIdentifier, error); task.Cancel (); }
public HttpFilesDownloadSession(string uniqueSessionId) { var config = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration(uniqueSessionId); downloadSession = NSUrlSession.FromConfiguration(config, this, new NSOperationQueue()); downloadTasks = new Dictionary<nuint, DownloadTaskInfo>(); DownloadQueue = new ObservableCollection<DownloadFileInfo>(); DownloadQueue.CollectionChanged += DownloadQueueOnCollectionChanged; }
public override void DidWriteData(NSUrlSession session, NSUrlSessionDownloadTask downloadTask, long bytesWritten, long totalBytesWritten, long totalBytesExpectedToWrite) { if (downloadTasks.ContainsKey(downloadTask.TaskIdentifier)) { var index = downloadTasks[downloadTask.TaskIdentifier].Index; var progress = totalBytesWritten/(float) totalBytesExpectedToWrite; OnFileDownloadProgress(index, progress); } }
public void Init(string sessionId, string url, TransferTaskMode mode) { using (var configuration = NSUrlSessionConfiguration.BackgroundSessionConfiguration(sessionId)) { _mode = mode; _sessionId = sessionId; _url = url; session = NSUrlSession.FromConfiguration(configuration); } }
public NativeMessageHandler(bool throwOnCaptiveNetwork, bool customSSLVerification, NativeCookieHandler cookieHandler = null) { session = NSUrlSession.FromConfiguration( NSUrlSessionConfiguration.DefaultSessionConfiguration, new DataTaskDelegate(this), null); this.throwOnCaptiveNetwork = throwOnCaptiveNetwork; this.customSSLVerification = customSSLVerification; this.DisableCaching = false; }
public override void DidWriteData (NSUrlSession session, NSUrlSessionDownloadTask downloadTask, long bytesWritten, long totalBytesWritten, long totalBytesExpectedToWrite) { Console.WriteLine ("Set Progress"); if (downloadTask == controller.downloadTask) { float progress = totalBytesWritten / (float)totalBytesExpectedToWrite; Console.WriteLine (string.Format ("DownloadTask: {0} progress: {1}", downloadTask, progress)); InvokeOnMainThread( () => { controller.ProgressView.Progress = progress; }); } }
public override void DidFinishDownloading (NSUrlSession session, NSUrlSessionDownloadTask downloadTask, NSUrl location) { CopyDownloadedImage (location); var message = new DownloadFinishedMessage () { FilePath = targetFileName, Url = downloadTask.OriginalRequest.Url.AbsoluteString }; MessagingCenter.Send<DownloadFinishedMessage> (message, "DownloadFinishedMessage"); }
public override void DidWriteData (NSUrlSession session, NSUrlSessionDownloadTask downloadTask, long bytesWritten, long totalBytesWritten, long totalBytesExpectedToWrite) { float percentage = (float)totalBytesWritten / (float)totalBytesExpectedToWrite; var message = new DownloadProgressMessage () { BytesWritten = bytesWritten, TotalBytesExpectedToWrite = totalBytesExpectedToWrite, TotalBytesWritten = totalBytesWritten, Percentage = percentage }; MessagingCenter.Send<DownloadProgressMessage> (message, "DownloadProgressMessage"); }
void InitializeSession () { using (var sessionConfig = UIDevice.CurrentDevice.CheckSystemVersion (8, 0) ? NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration (sessionId) : NSUrlSessionConfiguration.BackgroundSessionConfiguration (sessionId)) { sessionConfig.AllowsCellularAccess = true; sessionConfig.NetworkServiceType = NSUrlRequestNetworkServiceType.Default; sessionConfig.HttpMaximumConnectionsPerHost = 2; var sessionDelegate = new CustomSessionDownloadDelegate (targetFilename); this.session = NSUrlSession.FromConfiguration (sessionConfig, sessionDelegate, null); } }
public NetworkUrlSession(string identifier) { _transfers = new List<NetworkUrlSessionTransfer> (10); _urlSessionDelegate = new NetworkUrlSessionDelegate (this); NSUrlSessionConfiguration c = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration (identifier); NSOperationQueue q = new NSOperationQueue (); // only allow 1 file transfer at a time; SAMCTODO: not sure if this is best.. q.MaxConcurrentOperationCount = 1; _urlSession = NSUrlSession.FromConfiguration (c, _urlSessionDelegate, q); _urlSession.GetTasks( HandleNSUrlSessionPendingTasks ); IBackgroundUrlEventDispatcher appDelegate = UIApplication.SharedApplication.Delegate as IBackgroundUrlEventDispatcher; appDelegate.HandleEventsForBackgroundUrlEvent += HandleEventsForBackgroundUrl; }
public override void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error) { var fileUpload = this.Manager.GetUploadByTask (task); Debug.Assert(fileUpload != null, "Could not find FileUpload object for task!"); if(fileUpload == null) { return; } Debug.Assert(fileUpload.State == FileUpload.STATE.Started || fileUpload.State == FileUpload.STATE.Stopping, "Upload is in invalid state!"); var urlErrorCode = NSUrlError.Unknown; if(error != null) { Enum.TryParse<NSUrlError>(error.Code.ToString(), out urlErrorCode); } if(error == null) { fileUpload.Progress = 0f; fileUpload.Error = null; fileUpload.Response = fileUpload.UploadTask.Response as NSHttpUrlResponse; fileUpload.UploadTask = null; fileUpload.State = FileUpload.STATE.Uploaded; Console.WriteLine($"Completed upload {fileUpload}."); } else if(urlErrorCode == NSUrlError.Cancelled) { fileUpload.Error = null; fileUpload.UploadTask = null; fileUpload.State = FileUpload.STATE.Stopped; } else { // Upload was stopped by the network. fileUpload.Error = error; fileUpload.UploadTask = null; fileUpload.State = FileUpload.STATE.Failed; Console.WriteLine($"Upload failed: {fileUpload}"); } fileUpload.IsStateValid(); this.Manager.ActiveUploads.OnCollectionChanged(); }
/// <summary> /// Very misleading method name. Gets called if a download is done. Does not necessarily indicate an error /// unless the NSError parameter is not null. /// </summary> public override void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error) { if (error == null) { return; } Console.WriteLine ("DidCompleteWithError - Task: {0}, Error: {1}", task.TaskIdentifier, error); var downloadInfo = AppDelegate.GetDownloadInfoByTaskId (task.TaskIdentifier); if (downloadInfo != null) { downloadInfo.Reset (); } task.Cancel (); this.InvokeOnMainThread (() => this.controller.TableView.ReloadData()); }
void Dispose (bool disposing) { if (!_disposed) { lock (_lockObject) { if (_downloadSession != null) { _downloadSession.Dispose (); _downloadSession = null; } if (_uploadSession != null) { _uploadSession.Dispose (); _uploadSession = null; } } } _disposed = true; }
public async Task StartAsync() { Debug.Assert(this.session == null, "Session already initialized!"); // Create our view of the world based on the on-disk data structures. this.RestoreAllUploadsInWorkDirectory(); NSUrlSessionConfiguration config; if (!string.IsNullOrWhiteSpace(this.SessionIdentifier)) { Console.WriteLine($"Creating background session with identifier '{this.SessionIdentifier}'"); config = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration(this.SessionIdentifier); } else { Console.WriteLine("Creating ephemeral session configuration."); config = NSUrlSessionConfiguration.EphemeralSessionConfiguration; } // In our case we don't want any (NSURLCache-level) caching to get in the way // of our tests, so we always disable the cache. config.RequestCachePolicy = NSUrlRequestCachePolicy.ReloadIgnoringCacheData; config.Discretionary = true; this.session = NSUrlSession.FromConfiguration(config, new FileUploadDelegate(this), NSOperationQueue.MainQueue); config.Dispose(); // This is where things get wacky. From the point that we create the session (in the previous // line) to the point where the block passed to -getTasksWithCompletionHandler: runs, we can // be getting delegate callbacks for tasks whose corresponding upload objects are in the wrong // state (specifically, the task property isn't set and, in some cases, the state might be wrong). // A lot of the logic in -syncUploadTasks: and, especially -uploadForTask:, is designed to // compensate for that oddity. var activeTasks = await this.session.GetTasks2Async(); var activeUploadTasks = activeTasks.UploadTasks; NSOperationQueue.MainQueue.AddOperation(() => { this.SyncUploadTasks(activeUploadTasks); }); Console.WriteLine("FileUploadManager did start."); }
public NativeMessageHandler(bool throwOnCaptiveNetwork, bool customSSLVerification, NativeCookieHandler cookieHandler = null, SslProtocol? minimumSSLProtocol = null) { var configuration = NSUrlSessionConfiguration.DefaultSessionConfiguration; // System.Net.ServicePointManager.SecurityProtocol provides a mechanism for specifying supported protocol types // for System.Net. Since iOS only provides an API for a minimum and maximum protocol we are not able to port // this configuration directly and instead use the specified minimum value when one is specified. if (minimumSSLProtocol.HasValue) { configuration.TLSMinimumSupportedProtocol = minimumSSLProtocol.Value; } session = NSUrlSession.FromConfiguration( NSUrlSessionConfiguration.DefaultSessionConfiguration, new DataTaskDelegate(this), null); this.throwOnCaptiveNetwork = throwOnCaptiveNetwork; this.customSSLVerification = customSSLVerification; this.DisableCaching = false; }
public override void ViewDidLoad() { base.ViewDidLoad (); if (session == null) session = InitBackgroundSession (); // Perform any additional setup after loading the view, typically from a nib. progressView.Progress = 0; imageView.Hidden = false; progressView.Hidden = true; startButton.Clicked += Start; // Force the app to crash crashButton.Clicked += delegate { string s = null; s.ToString (); }; }
public async Task DownloadFileAsync (Uri url, string destination) { this.url = url.AbsoluteUri; if (downloadTask != null) return; if (session == null) session = InitBackgroundSession (); Destination = destination; if (!BackgroundDownloadManager.Tasks.TryGetValue (url.AbsoluteUri, out Tcs)) { Tcs = new TaskCompletionSource<bool> (); BackgroundDownloadManager.Tasks.Add (url.AbsoluteUri, Tcs); using (var request = new NSUrlRequest (new NSUrl (url.AbsoluteUri))) { downloadTask = session.CreateDownloadTask (request); downloadTask.Resume (); } } BackgroundDownloadManager.AddController (this.url, this); await Tcs.Task; }
/// <summary> /// Gets called if the download has been completed. /// </summary> public override void DidFinishDownloading(NSUrlSession session, NSUrlSessionDownloadTask downloadTask, NSUrl location) { // The download location will be a file location. var sourceFile = location.Path; // Construct a destination file name. var destFile = downloadTask.OriginalRequest.Url.AbsoluteString.Substring(downloadTask.OriginalRequest.Url.AbsoluteString.LastIndexOf("/") + 1); Console.WriteLine ("DidFinishDownloading - Task: {0}, Source file: {1}", downloadTask.TaskIdentifier, sourceFile); // Copy over to documents folder. Note that we must use NSFileManager here! File.Copy() will not be able to access the source location. NSFileManager fileManager = NSFileManager.DefaultManager; // Create the filename var documentsFolderPath = Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments); NSUrl destinationURL = NSUrl.FromFilename(Path.Combine(documentsFolderPath, destFile)); // Update download info object. var downloadInfo = AppDelegate.GetDownloadInfoByTaskId (downloadTask.TaskIdentifier); // Remove any existing file in our destination NSError error; fileManager.Remove(destinationURL, out error); bool success = fileManager.Copy(sourceFile, destinationURL.Path, out error); if (success) { location = destinationURL; this.UpdateDownloadInfo (downloadInfo, DownloadInfo.STATUS.Completed, destinationURL); } else { this.UpdateDownloadInfo (downloadInfo, DownloadInfo.STATUS.Cancelled, null); Console.WriteLine ("Error during the copy: {0}", error.LocalizedDescription); } this.InvokeOnMainThread (() => this.controller.TableView.ReloadData()); }
public override void DidFinishEventsForBackgroundSession(NSUrlSession session) { }
public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action <NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) { var inflight = GetInflightData(task); if (inflight == null) { return; } // ToCToU for the callback var trustCallback = sessionHandler.TrustOverride; if (trustCallback != null && challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodServerTrust) { if (trustCallback(sessionHandler, challenge.ProtectionSpace.ServerSecTrust)) { var credential = new NSUrlCredential(challenge.ProtectionSpace.ServerSecTrust); completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential); } else { // user callback rejected the certificate, we want to set the exception, else the user will // see as if the request was cancelled. lock (inflight.Lock) { inflight.Exception = new HttpRequestException("An error occurred while sending the request.", new WebException("Error: TrustFailure")); } completionHandler(NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null); } return; } // case for the basic auth failing up front. As per apple documentation: // The URL Loading System is designed to handle various aspects of the HTTP protocol for you. As a result, you should not modify the following headers using // the addValue(_:forHTTPHeaderField:) or setValue(_:forHTTPHeaderField:) methods: // Authorization // Connection // Host // Proxy-Authenticate // Proxy-Authorization // WWW-Authenticate // but we are hiding such a situation from our users, we can nevertheless know if the header was added and deal with it. The idea is as follows, // check if we are in the first attempt, if we are (PreviousFailureCount == 0), we check the headers of the request and if we do have the Auth // header, it means that we do not have the correct credentials, in any other case just do what it is expected. if (challenge.PreviousFailureCount == 0) { var authHeader = inflight.Request?.Headers?.Authorization; if (!(string.IsNullOrEmpty(authHeader?.Scheme) && string.IsNullOrEmpty(authHeader?.Parameter))) { completionHandler(NSUrlSessionAuthChallengeDisposition.RejectProtectionSpace, null); return; } } if (sessionHandler.Credentials != null && TryGetAuthenticationType(challenge.ProtectionSpace, out string authType)) { NetworkCredential credentialsToUse = null; if (authType != RejectProtectionSpaceAuthType) { var uri = inflight.Request.RequestUri; credentialsToUse = sessionHandler.Credentials.GetCredential(uri, authType); } if (credentialsToUse != null) { var credential = new NSUrlCredential(credentialsToUse.UserName, credentialsToUse.Password, NSUrlCredentialPersistence.ForSession); completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential); } else { // Rejecting the challenge allows the next authentication method in the request to be delivered to // the DidReceiveChallenge method. Another authentication method may have credentials available. completionHandler(NSUrlSessionAuthChallengeDisposition.RejectProtectionSpace, null); } } else { completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, challenge.ProposedCredential); } }
public virtual void DidReceiveResponse(NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action <NSUrlSessionResponseDisposition> completionHandler) { Called_DidReceiveResponse = true; completionHandler(NSUrlSessionResponseDisposition.Allow); this.Client.ReceivedResponse(this, response, NSUrlCacheStoragePolicy.Allowed); }
public void CreateDataTaskAsync() { TestRuntime.AssertXcodeVersion(5, 0); NSUrlSession session = NSUrlSession.SharedSession; var url = new NSUrl("https://www.microsoft.com"); var tmpfile = Path.GetTempFileName(); File.WriteAllText(tmpfile, "TMPFILE"); var file_url = NSUrl.FromFilename(tmpfile); var file_data = NSData.FromFile(tmpfile); var request = new NSUrlRequest(url); var completed = false; var timeout = 30; /* CreateDataTask */ completed = false; Assert.IsTrue(TestRuntime.RunAsync(DateTime.Now.AddSeconds(timeout), async() => { await session.CreateDataTaskAsync(request); completed = true; }, () => completed), "CreateDataTask a"); completed = false; Assert.IsTrue(TestRuntime.RunAsync(DateTime.Now.AddSeconds(timeout), async() => { await session.CreateDataTaskAsync(url); completed = true; }, () => completed), "CreateDataTask b"); /* CreateDownloadTask */ completed = false; Assert.IsTrue(TestRuntime.RunAsync(DateTime.Now.AddSeconds(timeout), async() => { await session.CreateDownloadTaskAsync(request); completed = true; }, () => completed), "CreateDownloadTask a"); completed = false; Assert.IsTrue(TestRuntime.RunAsync(DateTime.Now.AddSeconds(timeout), async() => { await session.CreateDownloadTaskAsync(url); completed = true; }, () => completed), "CreateDownloadTask b"); /* CreateUploadTask */ completed = false; Assert.IsTrue(TestRuntime.RunAsync(DateTime.Now.AddSeconds(timeout), async() => { try { var uploadRequest = new NSMutableUrlRequest(url); uploadRequest.HttpMethod = "POST"; await session.CreateUploadTaskAsync(uploadRequest, file_url); } catch /* (Exception ex) */ { // Console.WriteLine ("Ex: {0}", ex); } finally { completed = true; } }, () => completed), "CreateUploadTask a"); completed = false; Assert.IsTrue(TestRuntime.RunAsync(DateTime.Now.AddSeconds(timeout), async() => { try { var uploadRequest = new NSMutableUrlRequest(url); uploadRequest.HttpMethod = "POST"; await session.CreateUploadTaskAsync(uploadRequest, file_data); } catch /* (Exception ex) */ { // Console.WriteLine ("Ex: {0}", ex); } finally { completed = true; } }, () => completed), "CreateUploadTask b"); }
public override void DidReceiveResponse(NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action <NSUrlSessionResponseDisposition> completionHandler) { var inflight = GetInflightData(dataTask); if (inflight == null) { return; } try { var urlResponse = (NSHttpUrlResponse)response; var status = (int)urlResponse.StatusCode; var content = new NSUrlSessionDataTaskStreamContent(inflight.Stream, () => { if (!inflight.Completed) { dataTask.Cancel(); } inflight.Disposed = true; inflight.Stream.TrySetException(new ObjectDisposedException("The content stream was disposed.")); sessionHandler.RemoveInflightData(dataTask); }, inflight.CancellationToken); // NB: The double cast is because of a Xamarin compiler bug var httpResponse = new HttpResponseMessage((HttpStatusCode)status) { Content = content, RequestMessage = inflight.Request }; httpResponse.RequestMessage.RequestUri = new Uri(urlResponse.Url.AbsoluteString); foreach (var v in urlResponse.AllHeaderFields) { // NB: Cocoa trolling us so hard by giving us back dummy dictionary entries if (v.Key == null || v.Value == null) { continue; } // NSUrlSession tries to be smart with cookies, we will not use the raw value but the ones provided by the cookie storage if (v.Key.ToString() == SetCookie) { continue; } httpResponse.Headers.TryAddWithoutValidation(v.Key.ToString(), v.Value.ToString()); httpResponse.Content.Headers.TryAddWithoutValidation(v.Key.ToString(), v.Value.ToString()); } var cookies = session.Configuration.HttpCookieStorage.CookiesForUrl(response.Url); for (var index = 0; index < cookies.Length; index++) { httpResponse.Headers.TryAddWithoutValidation(SetCookie, cookies [index].GetHeaderValue()); } inflight.Response = httpResponse; // We don't want to send the response back to the task just yet. Because we want to mimic .NET behavior // as much as possible. When the response is sent back in .NET, the content stream is ready to read or the // request has completed, because of this we want to send back the response in DidReceiveData or DidCompleteWithError if (dataTask.State == NSUrlSessionTaskState.Suspended) { dataTask.Resume(); } } catch (Exception ex) { inflight.CompletionSource.TrySetException(ex); inflight.Stream.TrySetException(ex); sessionHandler.RemoveInflightData(dataTask); } completionHandler(NSUrlSessionResponseDisposition.Allow); }
public override void DidReceiveData (NSUrlSession session, NSUrlSessionDataTask dataTask, NSData byteData) { var data = getResponseForTask(dataTask); var bytes = byteData.ToArray(); // NB: If we're cancelled, we still might have one more chunk // of data that attempts to be delivered if (data.IsCompleted) return; data.ResponseBody.AddByteArray(bytes); }
public virtual void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error) { throw new NotImplementedException(); }
public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action <NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) { if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodNTLM) { NetworkCredential credentialsToUse; if (This.Credentials != null) { if (This.Credentials is NetworkCredential) { credentialsToUse = (NetworkCredential)This.Credentials; } else { var uri = this.getResponseForTask(task).Request.RequestUri; credentialsToUse = This.Credentials.GetCredential(uri, "NTLM"); } var credential = new NSUrlCredential(credentialsToUse.UserName, credentialsToUse.Password, NSUrlCredentialPersistence.ForSession); completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential); } return; } if (!This.customSSLVerification) { goto doDefault; } if (challenge.ProtectionSpace.AuthenticationMethod != "NSURLAuthenticationMethodServerTrust") { goto doDefault; } if (ServicePointManager.ServerCertificateValidationCallback == null) { goto doDefault; } // Convert Mono Certificates to .NET certificates and build cert // chain from root certificate var serverCertChain = challenge.ProtectionSpace.ServerSecTrust; var chain = new X509Chain(); X509Certificate2 root = null; var errors = SslPolicyErrors.None; if (serverCertChain == null || serverCertChain.Count == 0) { errors = SslPolicyErrors.RemoteCertificateNotAvailable; goto sslErrorVerify; } if (serverCertChain.Count == 1) { errors = SslPolicyErrors.RemoteCertificateChainErrors; goto sslErrorVerify; } var netCerts = Enumerable.Range(0, serverCertChain.Count) .Select(x => serverCertChain[x].ToX509Certificate2()) .ToArray(); for (int i = 1; i < netCerts.Length; i++) { chain.ChainPolicy.ExtraStore.Add(netCerts[i]); } root = netCerts[0]; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0); chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; if (!chain.Build(root)) { errors = SslPolicyErrors.RemoteCertificateChainErrors; goto sslErrorVerify; } var subject = root.Subject; var subjectCn = cnRegex.Match(subject).Groups[1].Value; if (String.IsNullOrWhiteSpace(subjectCn) || !Utility.MatchHostnameToPattern(task.CurrentRequest.Url.Host, subjectCn)) { errors = SslPolicyErrors.RemoteCertificateNameMismatch; goto sslErrorVerify; } sslErrorVerify: var hostname = task.CurrentRequest.Url.Host; bool result = ServicePointManager.ServerCertificateValidationCallback(hostname, root, chain, errors); if (result) { completionHandler( NSUrlSessionAuthChallengeDisposition.UseCredential, NSUrlCredential.FromTrust(challenge.ProtectionSpace.ServerSecTrust)); } else { completionHandler(NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null); } return; doDefault: completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, challenge.ProposedCredential); return; }
public NativeMessageHandler(bool throwOnCaptiveNetwork, TLSConfig tLSConfig, NativeCookieHandler cookieHandler = null, IWebProxy proxy = null) { this.throwOnCaptiveNetwork = throwOnCaptiveNetwork; var configuration = NSUrlSessionConfiguration.DefaultSessionConfiguration; this.TLSConfig = tLSConfig; // System.Net.ServicePointManager.SecurityProtocol provides a mechanism for specifying supported protocol types // for System.Net. Since iOS only provides an API for a minimum and maximum protocol we are not able to port // this configuration directly and instead use the specified minimum value when one is specified. configuration.TLSMinimumSupportedProtocol = SslProtocol.Tls_1_2; if (!TLSConfig.DangerousAcceptAnyServerCertificateValidator && TLSConfig.Pins != null && TLSConfig.Pins.Count > 0) { this.CertificatePinner = new CertificatePinner(); foreach (var pin in TLSConfig.Pins) { this.CertificatePinner.AddPins(pin.Hostname, pin.PublicKeys); } } SetClientCertificate(TLSConfig.ClientCertificate); // NSUrlSessionConfiguration.DefaultSessionConfiguration uses the default NSHttpCookieStorage.SharedStorage // PR: Proxy has been supported on iOS #19 if (proxy != null && proxy is WebProxy) { var webProxy = proxy as WebProxy; NSObject[] values = { NSObject.FromObject(webProxy.Address.Host), NSNumber.FromInt32(webProxy.Address.Port), NSNumber.FromInt32(1) }; NSObject[] keys = { NSObject.FromObject("HTTPSProxy"), NSObject.FromObject("HTTPSPort"), NSObject.FromObject("HTTPSEnable") }; var proxyDict = NSDictionary.FromObjectsAndKeys(values, keys); configuration.ConnectionProxyDictionary = proxyDict; if (webProxy.Credentials != null) { var credentials = (NetworkCredential)webProxy.Credentials; var authData = string.Format("{0}:{1}", credentials.UserName, credentials.Password); var authHeaderValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(authData)); NSObject[] hValues = { NSObject.FromObject(authHeaderValue) }; NSObject[] hKeys = { NSObject.FromObject("Proxy-Authorization") }; var headers = NSDictionary.FromObjectsAndKeys(hValues, hKeys); configuration.HttpAdditionalHeaders = headers; } } var urlSessionDelegate = new DataTaskDelegate(this); session = NSUrlSession.FromConfiguration(configuration, (INSUrlSessionDelegate)urlSessionDelegate, null); }
public override void WillPerformHttpRedirection(NSUrlSession session, NSUrlSessionTask task, NSHttpUrlResponse response, NSUrlRequest newRequest, Action <NSUrlRequest> completionHandler) { NSUrlRequest nextRequest = (nativeHandler.AllowAutoRedirect ? newRequest : null); completionHandler(nextRequest); }
public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action <NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) { // TODO: add NSUrlProtectionSpace.HTTPSProxy case if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodNTLM) { NetworkCredential credentialsToUse; if (nativeHandler.Credentials != null) { if (nativeHandler.Credentials is NetworkCredential) { credentialsToUse = (NetworkCredential)nativeHandler.Credentials; } else { var uri = this.getResponseForTask(task).Request.RequestUri; credentialsToUse = nativeHandler.Credentials.GetCredential(uri, "NTLM"); } var credential = new NSUrlCredential(credentialsToUse.UserName, credentialsToUse.Password, NSUrlCredentialPersistence.ForSession); completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential); } return; } if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodServerTrust) { var errors = SslPolicyErrors.None; if (nativeHandler.TLSConfig.DangerousAcceptAnyServerCertificateValidator) { goto sslErrorVerify; } // Convert java certificates to .NET certificates and build cert chain from root certificate var serverCertChain = challenge.ProtectionSpace.ServerSecTrust; var chain = new X509Chain(); X509Certificate2 root = null; // Build certificate chain and check for errors if (serverCertChain == null || serverCertChain.Count == 0) {//no cert at all errors = SslPolicyErrors.RemoteCertificateNotAvailable; PinningFailureMessage = FailureMessages.NoCertAtAll; goto sslErrorVerify; } if (serverCertChain.Count == 1) {//no root? errors = SslPolicyErrors.RemoteCertificateChainErrors; PinningFailureMessage = FailureMessages.NoRoot; goto sslErrorVerify; } var netCerts = Enumerable.Range(0, serverCertChain.Count) .Select(x => serverCertChain[x].ToX509Certificate2()) .ToArray(); for (int i = 1; i < netCerts.Length; i++) { chain.ChainPolicy.ExtraStore.Add(netCerts[i]); } root = netCerts[0]; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0); chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; if (!chain.Build(root)) { errors = SslPolicyErrors.RemoteCertificateChainErrors; PinningFailureMessage = FailureMessages.ChainError; goto sslErrorVerify; } var hostname = task.CurrentRequest.Url.Host; var subject = root.Subject; var subjectCn = cnRegex.Match(subject).Groups[1].Value; if (string.IsNullOrWhiteSpace(subjectCn) || !Utility.MatchHostnameToPattern(hostname, subjectCn)) { var subjectAn = root.ParseSubjectAlternativeName(); if (!subjectAn.Contains(hostname)) { errors = SslPolicyErrors.RemoteCertificateNameMismatch; PinningFailureMessage = FailureMessages.SubjectNameMismatch; goto sslErrorVerify; } } if (nativeHandler.CertificatePinner != null) { if (!nativeHandler.CertificatePinner.HasPins(hostname)) { errors = SslPolicyErrors.RemoteCertificateNameMismatch; PinningFailureMessage = FailureMessages.NoPinsProvided + " " + hostname; goto sslErrorVerify; } if (!nativeHandler.CertificatePinner.Check(hostname, root.RawData)) { errors = SslPolicyErrors.RemoteCertificateNameMismatch; PinningFailureMessage = FailureMessages.PinMismatch; } } sslErrorVerify: if (errors == SslPolicyErrors.None) { completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, NSUrlCredential.FromTrust(challenge.ProtectionSpace.ServerSecTrust)); } else { completionHandler(NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null); } return; } if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodClientCertificate) { completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, nativeHandler.UrlCredential); return; } completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, challenge.ProposedCredential); }
public override void WillCacheResponse(NSUrlSession session, NSUrlSessionDataTask dataTask, NSCachedUrlResponse proposedResponse, Action <NSCachedUrlResponse> completionHandler) { completionHandler(nativeHandler.DisableCaching ? null : proposedResponse); }
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 (nativeHandler.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()); }) { 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); }
public override void WillCacheResponse (NSUrlSession session, NSUrlSessionDataTask dataTask, NSCachedUrlResponse proposedResponse, Action<NSCachedUrlResponse> completionHandler) { completionHandler (This.DisableCaching ? null : proposedResponse); }
public virtual void DidFinishCollectingMetrics(NSUrlSession session, NSUrlSessionTask task, NSUrlSessionTaskMetrics metrics) { throw new NotImplementedException(); }
public override void WillPerformHttpRedirection(NSUrlSession session, NSUrlSessionTask task, NSHttpUrlResponse response, NSUrlRequest newRequest, Action<NSUrlRequest> completionHandler) { NSUrlRequest nextRequest = (This.AllowAutoRedirect ? newRequest : null); completionHandler(nextRequest); }
public Flickr() { session = NSUrlSession.SharedSession; }
public override void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error) { Console.WriteLine(string.Format("DidCompleteWithError TaskId: {0}{1}", task.TaskIdentifier, (error == null ? "" : " Error: " + error.Description))); NSMutableData _data = null; if (uploadData.ContainsKey(task.TaskIdentifier)) { _data = uploadData[task.TaskIdentifier]; uploadData.Remove(task.TaskIdentifier); } else { _data = new NSMutableData(); } NSString dataString = NSString.FromData(_data, NSStringEncoding.UTF8); var message = dataString == null ? string.Empty : $"{dataString}"; var responseError = false; NSHttpUrlResponse response = null; string[] parts = task.TaskDescription.Split('|'); if (task.Response is NSHttpUrlResponse) { response = task.Response as NSHttpUrlResponse; Console.WriteLine("HTTP Response {0}", response); Console.WriteLine("HTTP Status {0}", response.StatusCode); responseError = response.StatusCode != 200 && response.StatusCode != 201; } System.Diagnostics.Debug.WriteLine("COMPLETE"); //Remove the temporal multipart file if (parts != null && parts.Length > 0 && File.Exists(parts[1])) { File.Delete(parts[1]); } if (parts == null || parts.Length == 0) { parts = new string[] { string.Empty, string.Empty } } ; if (error == null && !responseError) { var fileUploadResponse = new FileUploadResponse(message, (int)response?.StatusCode, parts[0]); uploadCompletionSource.SetResult(fileUploadResponse); FileUploadCompleted(this, fileUploadResponse); } else if (responseError) { var fileUploadResponse = new FileUploadResponse(message, (int)response?.StatusCode, parts[0]); uploadCompletionSource.SetResult(fileUploadResponse); FileUploadError(this, fileUploadResponse); } else { var fileUploadResponse = new FileUploadResponse(error.Description, (int)response?.StatusCode, parts[0]); uploadCompletionSource.SetResult(fileUploadResponse); FileUploadError(this, fileUploadResponse); } _data = null; }
public virtual void DidLoadTimeRange(NSUrlSession session, AVAssetDownloadTask assetDownloadTask, CMTimeRange timeRange, NSValue[] loadedTimeRanges, CMTimeRange timeRangeExpectedToLoad) { throw new NotImplementedException(); }
public virtual void DidReceiveData(NSUrlSession session, NSUrlSessionDataTask dataTask, NSData data) { Called_DidReceiveData = true; this.Client.DataLoaded(this, data); }
public virtual void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, [BlockProxy(typeof(Trampolines.NIDActionArity2V0))] Action <NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) { throw new NotImplementedException(); }
public virtual void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action <NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) { Called_DidReceiveChallenge = true; completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, null); }
public virtual void DidResolveMediaSelection(NSUrlSession session, AVAssetDownloadTask assetDownloadTask, AVMediaSelection resolvedMediaSelection) { throw new NotImplementedException(); }
public virtual void WillPerformHttpRedirection(NSUrlSession session, NSUrlSessionTask task, NSHttpUrlResponse response, NSUrlRequest newRequest, Action <NSUrlRequest> completionHandler) { Called_WillPerformHttpRedirection = true; completionHandler(newRequest); }
public virtual void DidSendBodyData(NSUrlSession session, NSUrlSessionTask task, long bytesSent, long totalBytesSent, long totalBytesExpectedToSend) { throw new NotImplementedException(); }
public virtual void NeedNewBodyStream(NSUrlSession session, NSUrlSessionTask task, [BlockProxy(typeof(Trampolines.NIDActionArity1V0))] Action <NSInputStream> completionHandler) { throw new NotImplementedException(); }
public virtual void WillPerformHttpRedirection(NSUrlSession session, NSUrlSessionTask task, NSHttpUrlResponse response, NSUrlRequest newRequest, [BlockProxy(typeof(Trampolines.NIDActionArity1V1))] Action <NSUrlRequest> completionHandler) { throw new NotImplementedException(); }
public override void DidFinishDownloading(NSUrlSession session, NSUrlSessionDownloadTask downloadTask, NSUrl location) { _uploadCompleted(this, new NSUrlEventArgs(location.ToString())); }
public static void DidFinishDownloadingToUrl(this IAVAssetDownloadDelegate This, NSUrlSession session, AVAssetDownloadTask assetDownloadTask, NSUrl location) { throw new NotImplementedException(); }
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); }
public static void DidLoadTimeRange(this IAVAssetDownloadDelegate This, NSUrlSession session, AVAssetDownloadTask assetDownloadTask, CMTimeRange timeRange, NSValue[] loadedTimeRanges, CMTimeRange timeRangeExpectedToLoad) { throw new NotImplementedException(); }
public override void DidCompleteWithError (NSUrlSession session, NSUrlSessionTask task, NSError error) { var data = getResponseForTask(task); data.IsCompleted = true; if (error != null) { var ex = createExceptionForNSError(error); // Pass the exception to the response data.FutureResponse.TrySetException(ex); data.ResponseBody.SetException(ex); return; } data.ResponseBody.Complete(); lock (This.inflightRequests) { This.inflightRequests.Remove(task); } }
public static void DidResolveMediaSelection(this IAVAssetDownloadDelegate This, NSUrlSession session, AVAssetDownloadTask assetDownloadTask, AVMediaSelection resolvedMediaSelection) { throw new NotImplementedException(); }
public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) { if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodNTLM) { NetworkCredential credentialsToUse; if (This.Credentials != null) { if (This.Credentials is NetworkCredential) { credentialsToUse = (NetworkCredential)This.Credentials; } else { var uri = this.getResponseForTask(task).Request.RequestUri; credentialsToUse = This.Credentials.GetCredential(uri, "NTLM"); } var credential = new NSUrlCredential(credentialsToUse.UserName, credentialsToUse.Password, NSUrlCredentialPersistence.ForSession); completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential); } return; } if (!This.customSSLVerification) { goto doDefault; } if (challenge.ProtectionSpace.AuthenticationMethod != "NSURLAuthenticationMethodServerTrust") { goto doDefault; } if (ServicePointManager.ServerCertificateValidationCallback == null) { goto doDefault; } // Convert Mono Certificates to .NET certificates and build cert // chain from root certificate var serverCertChain = challenge.ProtectionSpace.ServerSecTrust; var chain = new X509Chain(); X509Certificate2 root = null; var errors = SslPolicyErrors.None; if (serverCertChain == null || serverCertChain.Count == 0) { errors = SslPolicyErrors.RemoteCertificateNotAvailable; goto sslErrorVerify; } if (serverCertChain.Count == 1) { errors = SslPolicyErrors.RemoteCertificateChainErrors; goto sslErrorVerify; } var netCerts = Enumerable.Range(0, serverCertChain.Count) .Select(x => serverCertChain[x].ToX509Certificate2()) .ToArray(); for (int i = 1; i < netCerts.Length; i++) { chain.ChainPolicy.ExtraStore.Add(netCerts[i]); } root = netCerts[0]; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0); chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; if (!chain.Build(root)) { errors = SslPolicyErrors.RemoteCertificateChainErrors; goto sslErrorVerify; } var subject = root.Subject; var subjectCn = cnRegex.Match(subject).Groups[1].Value; if (String.IsNullOrWhiteSpace(subjectCn) || !Utility.MatchHostnameToPattern(task.CurrentRequest.Url.Host, subjectCn)) { errors = SslPolicyErrors.RemoteCertificateNameMismatch; goto sslErrorVerify; } sslErrorVerify: var hostname = task.CurrentRequest.Url.Host; bool result = ServicePointManager.ServerCertificateValidationCallback(hostname, root, chain, errors); if (result) { completionHandler( NSUrlSessionAuthChallengeDisposition.UseCredential, NSUrlCredential.FromTrust(challenge.ProtectionSpace.ServerSecTrust)); } else { completionHandler(NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null); } return; doDefault: completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, challenge.ProposedCredential); return; }
public static async Task <IEnumerable <HttpTransfer> > QueryTransfers(this NSUrlSession session, QueryFilter?filter) { var tasks = await session.QueryTasks(filter); return(tasks.Select(x => x.FromNative())); }
public virtual void DidFinishDownloadingToUrl(NSUrlSession session, AVAssetDownloadTask assetDownloadTask, NSUrl location) { throw new NotImplementedException(); }
public override void DidFinishEventsForBackgroundSession (NSUrlSession session) { var handler = AppDelegate.BackgroundSessionCompletionHandler; AppDelegate.BackgroundSessionCompletionHandler = null; if (handler != null) { handler.Invoke (); } }