Ejemplo n.º 1
0
        async Task <bool> ExtractPartAndValidate(PartialZipDownload part, Stream partInputStream, string cacheDirectory)
        {
            string fileHash = null;

            var outputPath = GetOutputPath(cacheDirectory, part);

            using (var iis = new System.IO.Compression.DeflateStream(partInputStream, System.IO.Compression.CompressionMode.Decompress))
                //using (var iis = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream (partInputStream, new ICSharpCode.SharpZipLib.Zip.Compression.Inflater (true)))
                using (var fs = File.Open(outputPath, FileMode.Create)) {
                    await iis.CopyToAsync(fs).ConfigureAwait(false);

                    await fs.FlushAsync().ConfigureAwait(false);

                    fs.Seek(0, SeekOrigin.Begin);
                    fileHash = DownloadUtils.HashSha256(fs);
                    LogDebugMessage("Hash of Downloaded File: {0}", fileHash);

                    fs.Close();
                }

            if (!string.IsNullOrEmpty(part.Sha256) && !part.Sha256.Equals(fileHash, StringComparison.InvariantCultureIgnoreCase))
            {
                // TODO: HANDLE
                LogMessage("File SHA256 Hash was invalid, deleting file: {0}", part.ToFile);
                File.Delete(outputPath);
                return(false);
            }

            // Run through our AAR fixups if it's android
            if (IsAndroid)
            {
                AndroidAarFixups.FixupAar(outputPath, AndroidFixManifests, Log);
            }

            return(true);
        }
Ejemplo n.º 2
0
        async Task <bool> MakeSureLibraryIsInPlace(XamarinBuildDownload xbd, CancellationToken token)
        {
            // Skip extraction if the file is already in place
            var flagFile = xbd.DestinationDir + ".unpacked";

            if (File.Exists(flagFile))
            {
                return(true);
            }

            try {
                Directory.CreateDirectory(xbd.DestinationDir);
            } catch (Exception ex) {
                LogCodedError(ThisOrThat(xbd.CustomErrorCode, ErrorCodes.DirectoryCreateFailed), ThisOrThat(xbd.CustomErrorMessage, () => string.Format("Failed to create directory '{0}'.", xbd.DestinationDir)));
                LogMessage("Directory creation failure reason: " + ex.ToString(), MessageImportance.High);
                return(false);
            }

            var lockFile = xbd.DestinationDir + ".locked";

            using (var lockStream = DownloadUtils.ObtainExclusiveFileLock(lockFile, Token, TimeSpan.FromSeconds(xbd.ExclusiveLockTimeout), this)) {
                if (lockStream == null)
                {
                    LogCodedError(ErrorCodes.ExclusiveLockTimeout, "Timed out waiting for exclusive file lock on: {0}", lockFile);
                    LogMessage("Timed out waiting for an exclusive file lock on: " + lockFile, MessageImportance.High);
                    return(false);
                }

                if (!File.Exists(xbd.CacheFile) || !IsValidDownload(xbd.DestinationDir + ".sha256", xbd.CacheFile, xbd.Sha256))
                {
                    try {
                        int progress = -1;
                        DownloadProgressChangedEventHandler downloadHandler = (o, e) => {
                            if (e.ProgressPercentage % 10 != 0 || progress == e.ProgressPercentage)
                            {
                                return;
                            }
                            progress = e.ProgressPercentage;
                            LogMessage(
                                "\t({0}/{1}b), total {2:F1}%", e.BytesReceived, e.TotalBytesToReceive, e.ProgressPercentage
                                );
                        };
                        using (var client = new WebClient()) {
                            client.DownloadProgressChanged += downloadHandler;
                            LogMessage("  Downloading {0} to {1}", xbd.Url, xbd.CacheFile);
                            client.DownloadFileTaskAsync(xbd.Url, xbd.CacheFile).Wait(token);

                            // Run through our AAR fixups if it's android
                            if (IsAndroid)
                            {
                                AndroidAarFixups.FixupAar(xbd.CacheFile, AndroidFixManifests, Log);
                            }

                            LogMessage("  Downloading Complete");
                            client.DownloadProgressChanged -= downloadHandler;
                        }
                    } catch (Exception e) {
                        LogCodedError(ThisOrThat(xbd.CustomErrorCode, ErrorCodes.DownloadFailed), ThisOrThat(xbd.CustomErrorMessage, () => string.Format("Download failed. Please download {0} to a file called {1}.", xbd.Url, xbd.CacheFile)));
                        LogMessage("Download failure reason: " + e.GetBaseException().Message, MessageImportance.High);
                        File.Delete(xbd.CacheFile);
                        return(false);
                    }
                }

                if (!File.Exists(xbd.CacheFile))
                {
                    LogCodedError(ThisOrThat(xbd.CustomErrorCode, ErrorCodes.DownloadedFileMissing), ThisOrThat(xbd.CustomErrorMessage, () => string.Format("Downloaded file '{0}' is missing.", xbd.CacheFile)));
                    return(false);
                }

                if (xbd.Kind == ArchiveKind.Uncompressed)
                {
                    var uncompressedCacheFile = xbd.CacheFile;
                    if (!string.IsNullOrEmpty(xbd.ToFile))
                    {
                        uncompressedCacheFile = xbd.ToFile;
                    }

                    File.Move(xbd.CacheFile, Path.Combine(xbd.DestinationDir, Path.GetFileName(uncompressedCacheFile)));
                    File.WriteAllText(flagFile, "This marks that the extraction completed successfully");
                    return(true);
                }
                else
                {
                    if (await ExtractArchive(xbd, flagFile, token))
                    {
                        File.WriteAllText(flagFile, "This marks that the extraction completed successfully");
                        return(true);
                    }
                }
            }

            // We will attempt to delete the lock file when we're done
            try {
                if (File.Exists(lockFile))
                {
                    File.Delete(lockFile);
                }
            } catch { }

            return(false);
        }