Advertisement
nerru86

51Degrees implementing custom auto update

Apr 9th, 2015
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.33 KB | None | 0 0
  1. using FiftyOne.Foundation.Mobile.Detection;
  2. using FiftyOne.Foundation.Mobile.Detection.Entities;
  3. using FiftyOne.Foundation.Mobile.Detection.Factories;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7. using System.IO;
  8. using System.IO.Compression;
  9. using System.Linq;
  10. using System.Net;
  11. using System.Security;
  12. using System.Security.Cryptography;
  13. using System.Text;
  14. using System.Threading.Tasks;
  15.  
  16. /*
  17.  * Purpose of this application is to provide an example of how auto update can
  18.  * be used with a custom implementation of the 51Degrees .NET device detection.
  19.  */
  20. namespace ConsoleApplication1
  21. {
  22.     class Program
  23.     {
  24.         internal const string AutoUpdateUrl = "https://51degrees.com/Products/Downloads/Premium.aspx";
  25.         internal static string[] licenceKeys = { "YOUR KEY" };
  26.         internal const string tempFile = "C:\\path\\to\\temp.dat";
  27.         internal const string dataFile = "C:\\path\\to\\FOD.dat";
  28.  
  29.         static void Main(string[] args)
  30.         {
  31.             //Simulate an existing provider.
  32.             Provider p = new Provider(StreamFactory.Create(dataFile));
  33.             Console.Write("Original data file: "+p.DataSet.Name);
  34.             Console.Write(" Published: "+p.DataSet.Published);
  35.             Console.WriteLine(".");
  36.  
  37.             WebClient client = new WebClient();
  38.             byte[] data = null;
  39.  
  40.             //Download file.
  41.             Console.Write("Commencing data download.");
  42.             try
  43.             {
  44.                 data = client.DownloadData(FullUrl(licenceKeys));
  45.             }
  46.             catch (Exception ex)
  47.             {
  48.                 Console.WriteLine("Download failed.");
  49.             }
  50.             Console.WriteLine(" Done.");
  51.  
  52.             Console.Write("Commencing md5 validation.");
  53.             // Validate the MD5 hash result.
  54.             try
  55.             {
  56.                 ValidateMD5(client, data);
  57.             }
  58.             catch (Exception ex)
  59.             {
  60.                 Console.WriteLine("md5 validation failed.");
  61.             }
  62.             Console.WriteLine(" Done.");
  63.  
  64.             //Temporary data set to check try and load data.
  65.             DataSet dataSet = null;
  66.  
  67.             Console.Write("Commencing data extraction.");
  68.             //Extract data.
  69.             using (var fs = File.Create(tempFile))
  70.             {
  71.                 using (var gs = new GZipStream(
  72.                     new MemoryStream(data), CompressionMode.Decompress))
  73.                 {
  74.                     byte[] buffer = new byte[1024 ^ 2];
  75.                     int count = 0;
  76.                     while ((count = gs.Read(buffer, 0, buffer.Length)) > 0)
  77.                     {
  78.                         fs.Write(buffer, 0, count);
  79.                     }
  80.                 }
  81.             }
  82.             Console.WriteLine(" Done.");
  83.  
  84.             Console.Write("Commencing data check.");
  85.             //Try to test downloaded data.
  86.             dataSet = StreamFactory.Create(tempFile);
  87.             Console.Write(" Dataset: "+dataSet.Name);
  88.             Console.Write(" Published: "+dataSet.Published);
  89.             Console.WriteLine(" Done.");
  90.  
  91.             //Compare published dates and number of properties to see if it's necessary to update.
  92.             if (dataSet.Published != p.DataSet.Published ||
  93.                 dataSet.Properties.Count != p.DataSet.Properties.Count)
  94.             {
  95.                 Console.WriteLine("Downloaded file is newer or has more properties, Updating.");
  96.                 // Rename the current master file to a temp file so enable the new
  97.                 // master file to take it's place and to rollback if there's a problem.
  98.                 var temp = String.Format("{0}.tmp", dataFile);
  99.  
  100.                 //Tear down the original provider to release the file.
  101.                 Console.Write("Disposing of the current Provider and temporary DataSet to release file locks.");
  102.                 p.DataSet.Dispose();
  103.                 dataSet.Dispose();
  104.                 Console.WriteLine(" Done.");
  105.  
  106.                 //If data file exists move it to temp location.
  107.                 Console.Write("Moving existing original data file.");
  108.                 if (File.Exists(dataFile))
  109.                     File.Move(dataFile, temp);
  110.                 Console.WriteLine(" Done.");
  111.  
  112.                 //Copy downloaded data file in place of the existing one.
  113.                 Console.Write("Copying the new data file.");
  114.                 File.Copy(tempFile, dataFile);
  115.                 Console.WriteLine(" Done.");
  116.  
  117.                 //Clean up temporary files.
  118.                 Console.Write("Removing temporary data files.");
  119.                 if (File.Exists(temp))
  120.                 {
  121.                     try
  122.                     {
  123.                         File.Delete(temp);
  124.                     } catch (Exception ex) {
  125.                         Console.Write(" Failed to delete temp.");
  126.                     }
  127.                 }
  128.                 if (File.Exists(tempFile))
  129.                 {
  130.                     try
  131.                     {
  132.                         File.Delete(tempFile);
  133.                     }
  134.                     catch (Exception ex)
  135.                     {
  136.                         Console.Write(" Failed to delete temporary downloaded file.");
  137.                     }
  138.                 }
  139.                 Console.WriteLine(" Done.");
  140.  
  141.                 //Create new provider.
  142.                 Console.Write("Update finished. Recreating provider.");
  143.                 p = new Provider(StreamFactory.Create(dataFile));
  144.                 Console.WriteLine(" Done.");
  145.  
  146.                 Console.Write("New file is: "+p.DataSet.Name);
  147.                 Console.WriteLine(" Published: "+p.DataSet.Published);
  148.  
  149.             }
  150.             else
  151.             {
  152.                 Console.WriteLine("Update was not required.");
  153.             }
  154.  
  155.             //Dispose of the dataset.
  156.             p.DataSet.Dispose();
  157.             Console.ReadLine();
  158.         }
  159.  
  160.         /// <summary>
  161.         /// Used to get the url for data download.
  162.         /// </summary>
  163.         /// <param name="licences">An array of licences to try.</param>
  164.         /// <returns>The full url including all parameters needed to download
  165.         /// the device data file.</returns>
  166.         internal static string FullUrl(string[] licences)
  167.         {
  168.             List<string> parameters = new List<string>();
  169.             parameters.Add(String.Format("LicenseKeys={0}", String.Join("|", licences)));
  170.             parameters.Add(String.Format("Download={0}", bool.TrueString));
  171.             parameters.Add("Type=BinaryV3");
  172.  
  173.             return String.Format("{0}?{1}",
  174.                 AutoUpdateUrl,
  175.                 String.Join("&", parameters.ToArray()));
  176.         }
  177.  
  178.         /// <summary>
  179.         /// Checks the MD5 hash of the data against the expected value.
  180.         /// </summary>
  181.         /// <param name="client"></param>
  182.         /// <param name="data"></param>
  183.         internal static void ValidateMD5(WebClient client, byte[] data)
  184.         {
  185.             // Check the MD5 hash of the data downloaded.
  186.             string mdHash = client.ResponseHeaders["Content-MD5"];
  187.             if (mdHash != GetMd5Hash(data))
  188.                 throw new Exception(String.Format(
  189.                     "MD5 hash '{0}' validation failure with data downloaded from update URL '{1}'.",
  190.                     mdHash,
  191.                     client.BaseAddress));
  192.  
  193.         }
  194.  
  195.         private static string GetMd5Hash(byte[] value)
  196.         {
  197.             using (MD5 md5Hash = MD5.Create())
  198.                 return GetMd5Hash(md5Hash, value);
  199.         }
  200.  
  201.         private static string GetMd5Hash(MD5 md5Hash, byte[] value)
  202.         {
  203.             if (value == null)
  204.                 return String.Empty;
  205.  
  206.             // Convert the input string to a byte array and compute the hash.
  207.             byte[] data = md5Hash.ComputeHash(value);
  208.  
  209.             // Create a new Stringbuilder to collect the bytes
  210.             // and create a string.
  211.             StringBuilder sBuilder = new StringBuilder();
  212.  
  213.             // Loop through each byte of the hashed data
  214.             // and format each one as a hexadecimal string.
  215.             for (int i = 0; i < data.Length; i++)
  216.             {
  217.                 sBuilder.Append(data[i].ToString("x2"));
  218.             }
  219.  
  220.             // Return the hexadecimal string.
  221.             return sBuilder.ToString();
  222.         }
  223.     }
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement