/// <summary> /// /// </summary> /// <param name="asynchronousResult"></param> private void downloadCallback(IAsyncResult asynchronousResult) { DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState; HttpWebRequest request = reqState.request; string callbackId = reqState.options.CallbackId; if (InProcDownloads.ContainsKey(reqState.options.Id)) { InProcDownloads.Remove(reqState.options.Id); } try { HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { // create the file if not exists if (!isoFile.FileExists(reqState.options.FilePath)) { var file = isoFile.CreateFile(reqState.options.FilePath); file.Close(); } using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, FileAccess.Write, isoFile)) { long totalBytes = response.ContentLength; int bytesRead = 0; using (BinaryReader reader = new BinaryReader(response.GetResponseStream())) { using (BinaryWriter writer = new BinaryWriter(fileStream)) { int BUFFER_SIZE = 1024; byte[] buffer; while (true) { buffer = reader.ReadBytes(BUFFER_SIZE); // fire a progress event ? bytesRead += buffer.Length; if (buffer.Length > 0) { writer.Write(buffer); } else { writer.Close(); reader.Close(); fileStream.Close(); break; } } } } } } File.FileEntry entry = new File.FileEntry(reqState.options.FilePath); DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId); } catch (IsolatedStorageException) { // Trying to write the file somewhere within the IsoStorage. DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)), callbackId); } catch (SecurityException) { // Trying to write the file somewhere not allowed. DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)), callbackId); } catch (WebException webex) { // TODO: probably need better work here to properly respond with all http status codes back to JS // Right now am jumping through hoops just to detect 404. HttpWebResponse response = (HttpWebResponse)webex.Response; if ((webex.Status == WebExceptionStatus.ProtocolError && response.StatusCode == HttpStatusCode.NotFound) || webex.Status == WebExceptionStatus.UnknownError) { // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!! // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away." // FACEPALM // Or just cast it to an int, whiner ... -jm int statusCode = (int)response.StatusCode; string body = ""; using (Stream streamResponse = response.GetResponseStream()) { using (StreamReader streamReader = new StreamReader(streamResponse)) { body = streamReader.ReadToEnd(); } } FileTransferError ftError = new FileTransferError(ConnectionError, null, null, statusCode, body); DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ftError), callbackId); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)), callbackId); } } catch (Exception) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)), callbackId); } }
/// <summary> /// /// </summary> /// <param name="asynchronousResult"></param> private async void downloadCallback(IAsyncResult asynchronousResult) { DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState; HttpWebRequest request = reqState.request; string filepath = reqState.options.FilePath; string filename; if (String.IsNullOrEmpty(filepath)) { return; } string[] split = filepath.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries); if (split.Length < 1) { return; } else { filename = split[split.Length - 1]; } try { HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); StorageFolder storagefolder = await StorageFolder.GetFolderFromPathAsync(Windows.Storage.ApplicationData.Current.LocalFolder.Path); await storagefolder.CreateFileAsync(filename); StorageFile storagefile = await StorageFile.GetFileFromPathAsync(storagefolder.Path + "\\" + filename); Stream fileStream = await storagefile.OpenStreamForWriteAsync(); long totalBytes = response.ContentLength; int bytesRead = 0; using (BinaryReader reader = new BinaryReader(response.GetResponseStream())) { using (BinaryWriter writer = new BinaryWriter(fileStream)) { int BUFFER_SIZE = 1024; byte[] buffer; while (true) { buffer = reader.ReadBytes(BUFFER_SIZE); // fire a progress event ? bytesRead += buffer.Length; if (buffer.Length > 0) { writer.Write(buffer); } else { break; } } } } File.FileEntry entry = new File.FileEntry(true, storagefolder.Path + "\\" + filename); DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry)); } catch (WebException webex) { // TODO: probably need better work here to properly respond with all http status codes back to JS // Right now am jumping through hoops just to detect 404. if ((((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound) || (webex.Status == WebExceptionStatus.UnknownError)) { // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!! // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away." // FACEPALM DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError, null, null, 404))); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError))); } } catch (Exception) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError))); } }
public async void download(string options) { TransferOptions downloadOptions = null; HttpWebRequest webRequest = null; string callbackId; try { // source, target, trustAllHosts, this._id, headers string[] optionStrings = JSON.JsonHelper.Deserialize <string[]>(options); downloadOptions = new TransferOptions(); downloadOptions.Url = optionStrings[0]; downloadOptions.FilePath = optionStrings[1]; bool trustAll = false; bool.TryParse(optionStrings[2], out trustAll); downloadOptions.TrustAllHosts = trustAll; downloadOptions.Id = optionStrings[3]; downloadOptions.Headers = optionStrings[4]; downloadOptions.CallbackId = callbackId = optionStrings[5]; } catch (Exception) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } try { // is the URL a local app file? if (downloadOptions.Url.StartsWith("x-wmapp0") || downloadOptions.Url.StartsWith("file:")) { using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { string cleanUrl = downloadOptions.Url.Replace("x-wmapp0:", "").Replace("file:", "").Replace("//", ""); // pre-emptively create any directories in the FilePath that do not exist string directoryName = getDirectoryName(downloadOptions.FilePath); if (!string.IsNullOrEmpty(directoryName) && !isoFile.DirectoryExists(directoryName)) { isoFile.CreateDirectory(directoryName); } // just copy from one area of iso-store to another ... if (isoFile.FileExists(downloadOptions.Url)) { isoFile.CopyFile(downloadOptions.Url, downloadOptions.FilePath); } else { // need to unpack resource from the dll Uri uri = new Uri(cleanUrl, UriKind.Relative); var resource = Application.GetResourceStream(uri); if (resource != null) { // create the file destination if (!isoFile.FileExists(downloadOptions.FilePath)) { var destFile = isoFile.CreateFile(downloadOptions.FilePath); destFile.Close(); } using (FileStream fileStream = new IsolatedStorageFileStream(downloadOptions.FilePath, FileMode.Open, FileAccess.Write, isoFile)) { long totalBytes = resource.Stream.Length; int bytesRead = 0; using (BinaryReader reader = new BinaryReader(resource.Stream)) { using (BinaryWriter writer = new BinaryWriter(fileStream)) { int BUFFER_SIZE = 1024; byte[] buffer; while (true) { buffer = reader.ReadBytes(BUFFER_SIZE); // fire a progress event ? bytesRead += buffer.Length; if (buffer.Length > 0) { writer.Write(buffer); DispatchFileTransferProgress(bytesRead, totalBytes, callbackId); } else { writer.Close(); reader.Close(); fileStream.Close(); break; } } } } } } } } File.FileEntry entry = File.FileEntry.GetEntry(downloadOptions.FilePath); if (entry != null) { DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, File.NOT_FOUND_ERR), callbackId); } return; } else { // otherwise it is web-bound, we will actually download it //Debug.WriteLine("Creating WebRequest for url : " + downloadOptions.Url); webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url); } } catch (Exception /*ex*/) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0))); return; } if (downloadOptions != null && webRequest != null) { DownloadRequestState state = new DownloadRequestState(); state.options = downloadOptions; state.request = webRequest; InProcDownloads[downloadOptions.Id] = state; // Associate cookies with the request // This is an async call, so we need to await it in order to preserve proper control flow await CopyCookiesFromWebBrowser(webRequest); if (!string.IsNullOrEmpty(downloadOptions.Headers)) { Dictionary <string, string> headers = parseHeaders(downloadOptions.Headers); foreach (string key in headers.Keys) { webRequest.Headers[key] = headers[key]; } } try { webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state); } catch (WebException) { // eat it } // dispatch an event for progress ( 0 ) lock (state) { if (!state.isCancelled) { var plugRes = new PluginResult(PluginResult.Status.OK, new FileTransferProgress()); plugRes.KeepCallback = true; plugRes.CallbackId = callbackId; DispatchCommandResult(plugRes, callbackId); } } } }
/// <summary> /// /// </summary> /// <param name="asynchronousResult"></param> private async void downloadCallback(IAsyncResult asynchronousResult) { DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState; HttpWebRequest request = reqState.request; string callbackId = reqState.options.CallbackId; try { HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); // send a progress change event DispatchFileTransferProgress(0, response.ContentLength, callbackId); StorageFile storageFile1; using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { // create any directories in the path that do not exist string directoryName = getDirectoryName(reqState.options.FilePath); if (!string.IsNullOrEmpty(directoryName) && !isoFile.DirectoryExists(directoryName)) { isoFile.CreateDirectory(directoryName); } // create the file if not exists if (!isoFile.FileExists(reqState.options.FilePath)) { var file = isoFile.CreateFile(reqState.options.FilePath); file.Close(); } using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.OpenOrCreate, FileAccess.Write, isoFile)) { long totalBytes = response.ContentLength; int bytesRead = 0; using (BinaryReader reader = new BinaryReader(response.GetResponseStream())) { using (BinaryWriter writer = new BinaryWriter(fileStream)) { int BUFFER_SIZE = 1024; byte[] buffer; while (true) { buffer = reader.ReadBytes(BUFFER_SIZE); // fire a progress event ? bytesRead += buffer.Length; if (buffer.Length > 0 && !reqState.isCancelled) { writer.Write(buffer); DispatchFileTransferProgress(bytesRead, totalBytes, callbackId); System.Threading.Thread.Sleep(1); } else { break; } } writer.Close(); reader.Close(); fileStream.Close(); StorageFolder installedLocation = Package.Current.InstalledLocation; StorageFile storageFile = await installedLocation.CreateFileAsync(Path.GetFileName(reqState.options.FilePath), CreationCollisionOption.OpenIfExists); storageFile1 = storageFile; Stream stream = await storageFile1.OpenStreamForWriteAsync(); try { stream.Write(buffer, 0, (int)buffer.Length); } finally { if (stream != null) { stream.Dispose(); } } StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder; StorageFile storedFile = await local.GetFileAsync(Path.GetFileName(reqState.options.FilePath)); Deployment.Current.Dispatcher.BeginInvoke(async() => { { await Windows.System.Launcher.LaunchFileAsync(storedFile); } }); var options = new Windows.System.LauncherOptions(); options.DisplayApplicationPicker = true; } } } if (reqState.isCancelled) { isoFile.DeleteFile(reqState.options.FilePath); } } if (reqState.isCancelled) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(AbortError)), callbackId); } else { File.FileEntry entry = new File.FileEntry(reqState.options.FilePath); DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId); } } catch (IsolatedStorageException) { // Trying to write the file somewhere within the IsoStorage. DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)), callbackId); } catch (SecurityException) { // Trying to write the file somewhere not allowed. DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)), callbackId); } catch (WebException webex) { // TODO: probably need better work here to properly respond with all http status codes back to JS // Right now am jumping through hoops just to detect 404. HttpWebResponse response = (HttpWebResponse)webex.Response; if ((webex.Status == WebExceptionStatus.ProtocolError && response.StatusCode == HttpStatusCode.NotFound) || webex.Status == WebExceptionStatus.UnknownError) { // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!! // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away." // FACEPALM // Or just cast it to an int, whiner ... -jm int statusCode = (int)response.StatusCode; string body = ""; using (Stream streamResponse = response.GetResponseStream()) { using (StreamReader streamReader = new StreamReader(streamResponse)) { body = streamReader.ReadToEnd(); } } FileTransferError ftError = new FileTransferError(ConnectionError, null, null, statusCode, body); DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ftError), callbackId); } else { lock (reqState) { if (!reqState.isCancelled) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)), callbackId); } else { Debug.WriteLine("It happened"); } } } } catch (Exception) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)), callbackId); } System.Threading.Thread.Sleep(1000); if (InProcDownloads.ContainsKey(reqState.options.Id)) { InProcDownloads.Remove(reqState.options.Id); } }