A provider with methods designed to be called from within web applications where HttpRequest objects can be used to provide the necessary evidence for detection.
Inheritance: Provider, IDisposable
コード例 #1
0
        /// <summary>
        /// Gets the JavaScript to send to the specific client device based on the
        /// request context provided.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private static string GetFeatureJavaScript(HttpContext context)
        {
            var queryString = context.Request.QueryString.ToString();
            var match       = WebProvider.GetMatch(context.Request);
            var features    = new List <string>();

            if (String.IsNullOrEmpty(queryString))
            {
                foreach (var property in WebProvider.ActiveProvider.DataSet.Properties.Where(i =>
                                                                                             i._valueType != Entities.Property.PropertyValueType.JavaScript))
                {
                    GetFeatureJavaScript(match, features, property);
                }
            }
            else
            {
                foreach (var propertyName in HttpUtility.UrlDecode(queryString).Split(
                             new char[] { ' ', ',', '&', '|' }))
                {
                    var property = WebProvider.ActiveProvider.DataSet.Properties.FirstOrDefault(i =>
                                                                                                i.Name.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase));
                    if (property != null)
                    {
                        GetFeatureJavaScript(match, features, property);
                    }
                }
            }
            return(String.Format("var FODF={{{0}}};", String.Join(",", features.ToArray())));
        }
コード例 #2
0
        /// <summary>
        /// Activates the data array containing the premium data.
        /// </summary>
        /// <param name="data">Data to activate</param>
        public static LicenceKeyResults Activate(byte[] data)
        {
            try
            {
                DataSet dataSet = null;

                // Validate the data provided is correct.
                try
                {
                    dataSet = StreamFactory.Create(data);
                }
                catch (MobileException ex)
                {
                    EventLog.Warn(ex);
                    return(LicenceKeyResults.DataInvalid);
                }

                // Check the configuration.
                try
                {
                    CheckConfig();
                }
                catch (Exception ex)
                {
                    EventLog.Warn(ex);
                    return(LicenceKeyResults.Config);
                }

                // Write the file to the binary data path.
                try
                {
                    File.WriteAllBytes(Detection.Configuration.Manager.BinaryFilePath, data);
                    File.SetLastAccessTimeUtc(Detection.Configuration.Manager.BinaryFilePath, dataSet.Published);
                }
                catch (IOException ex)
                {
                    EventLog.Warn(ex);
                    return(LicenceKeyResults.WriteDataFile);
                }

                // Switch in the new data to complete activation.
                WebProvider.Refresh();

                EventLog.Info(String.Format(
                                  "Activated binary data file '{0}' with new version " +
                                  "dated the '{1:d}'.",
                                  AutoUpdate.MasterBinaryDataFile.FullName,
                                  dataSet.Published));
            }
            catch (Exception ex)
            {
                EventLog.Warn(ex);
                return(LicenceKeyResults.GenericFailure);
            }

            return(LicenceKeyResults.Success);
        }
コード例 #3
0
ファイル: RequestHelper.cs プロジェクト: chj853/51degrees
 /// <summary>
 /// Writes information about the data set being used by the provider.
 /// </summary>
 /// <param name="writer"></param>
 /// <param name="provider"></param>
 private static void WriteProvider(XmlWriter writer, WebProvider provider)
 {
     if (provider != null)
     {
         writer.WriteStartElement("DataSet");
         writer.WriteElementString("Version", provider.DataSet.Version.ToString());
         writer.WriteElementString("Name", provider.DataSet.Name);
         writer.WriteEndElement();
     }
 }
コード例 #4
0
        /// <summary>
        /// Forces the application to reload the active provider on the next
        /// request.
        /// </summary>
        public static void Refresh()
        {
            var provider = _activeProvider;

            _activeProvider        = null;
            _activeProviderCreated = false;
            if (provider != null)
            {
                // Dispose of the old provider.
                provider.Dispose();
            }
        }
コード例 #5
0
        /// <summary>
        /// Downloads and updates the premium data file.
        /// </summary>
        internal static LicenceKeyResults Download(string[] licenceKeys)
        {
            var       status = LicenceKeyResults.InProgress;
            WebClient client = new WebClient();

            var compressedTempFile   = WebProvider.GetTempFileName();
            var uncompressedTempFile = String.Format("{0}.new", Manager.BinaryFilePath);

            try
            {
                // Wait until any other threads have finished executing.
                _autoDownloadUpdateSignal.WaitOne();

                // Download the data file to the compressed temporary file.
                status = DownloadFile(client, Manager.BinaryFilePath, compressedTempFile, licenceKeys);

                // Validate the MD5 hash of the download.
                if (status == LicenceKeyResults.InProgress)
                {
                    status = CheckedDownloadedFileMD5(client, compressedTempFile);
                }

                // Decompress the data file ready to create the data set.
                if (status == LicenceKeyResults.InProgress)
                {
                    status = Decompress(compressedTempFile, uncompressedTempFile);
                }

                // Validate that the data file can be used to create a provider.
                if (status == LicenceKeyResults.InProgress)
                {
                    status = ValidateDownloadedFile(uncompressedTempFile);
                }

                // Activate the data file downloaded for future use.
                if (status == LicenceKeyResults.InProgress)
                {
                    status = ActivateDownloadedFile(client, uncompressedTempFile);
                }
            }
            catch (Exception)
            {
                status = LicenceKeyResults.GenericFailure;
            }
            finally
            {
                File.Delete(compressedTempFile);
                File.Delete(uncompressedTempFile);
                client.Dispose();
                _autoDownloadUpdateSignal.Set();
            }
            return(status);
        }
コード例 #6
0
        /// <summary>
        /// Creates a new provider and then sets it as active provider
        /// </summary>
        public static bool Reload()
        {
            var newProvider = Create();

            if (newProvider == null)
            {
                return(false);
            }
            EventLog.Info("Replacing the active provider.");
            var oldProvider = _activeProvider;

            _activeProvider = newProvider;
            oldProvider?.Dispose();
            return(true);
        }
コード例 #7
0
 /// <summary>
 /// The application is being disposed of either due to a recycle event or
 /// shutdown. Ensure the active provider is disposed of to release resources.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private static void OnProcessExit(object sender, EventArgs e)
 {
     try
     {
         var provider = _activeProvider;
         if (provider != null)
         {
             provider.Dispose();
         }
     }
     finally
     {
         _activeProvider        = null;
         _activeProviderCreated = false;
     }
 }
コード例 #8
0
 /// <summary>
 /// Checks if a new data file is available for download and if it is
 /// newer than the current data on disk, if enough time has passed
 /// between now and the write time of the current data in memory. See
 /// Constants.AutoUpdateWait. This method is designed to be used in a
 /// seperate thread from the one performing detection.
 /// </summary>
 internal static void CheckForUpdate(object state)
 {
     try
     {
         // If licence keys are available auto update.
         if (LicenceKey.Keys.Length > 0)
         {
             // Check that there is a binary file, and that either the
             // active provider is not available indicating no source
             // data file, or if is available that the next update is
             // in the past, or that the device data being used is the
             // free lite version.
             if (MasterBinaryDataFile != null &&
                 (WebProvider.ActiveProvider == null ||
                  WebProvider.ActiveProvider.DataSet.NextUpdate <
                  DateTime.UtcNow ||
                  WebProvider.ActiveProvider.DataSet.Name == "Lite"))
             {
                 var downloadResult = Download(LicenceKey.Keys);
                 if (downloadResult ==
                     LicenceKeyResults.Success)
                 {
                     WebProvider.Refresh();
                 }
             }
         }
     }
     catch (ThreadAbortException ex)
     {
         EventLog.Warn(new MobileException(
                           "Auto update download thread aborted",
                           ex));
     }
     catch (Exception ex)
     {
         if (MasterBinaryDataFile != null && MasterBinaryDataFile.FullName != null)
         {
             EventLog.Warn(new MobileException(String.Format(
                                                   "Exception auto update download binary data file '{0}'.",
                                                   MasterBinaryDataFile.FullName), ex));
         }
         else
         {
             EventLog.Fatal(ex);
         }
     }
 }
コード例 #9
0
        /// <summary>
        /// Provides information to the web server about the requesting device.
        /// </summary>
        /// <param name="request">An HttpRequest that provides information about the source device.</param>
        /// <returns>A HttpBrowserCapabilities object containing information relevent to the device
        /// sources from 51Degrees.mobi.</returns>
        public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request)
        {
            var match = WebProvider.GetMatch(request);

            if (match != null)
            {
                // A provider is present so 51Degrees can be used to override
                // some of the returned values.
                return(new FiftyOneBrowserCapabilities(
                           base.GetBrowserCapabilities(request),
                           request,
                           match));
            }
            else
            {
                // No 51Degrees active provider is present so we have to use
                // the base capabilities only.
                return(base.GetBrowserCapabilities(request));
            }
        }
コード例 #10
0
        /// <summary>
        /// Provides information to the web server about the requesting device.
        /// </summary>
        /// <param name="request">
        /// HttpRequest that provides information about the source device.
        /// </param>
        /// <returns>
        /// A HttpBrowserCapabilities object containing information which
        /// retrieves device data from 51Degrees.
        /// </returns>
        public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request)
        {
            HttpBrowserCapabilities caps;
            var baseCaps = base.GetBrowserCapabilities(request);
            var match    = WebProvider.GetMatch(request);

            if (match != null)
            {
                // A provider is present so 51Degrees can be used to override
                // some of the returned values.
                caps = new FiftyOneBrowserCapabilities(
                    baseCaps,
                    request,
                    match);

                // Copy the adapters from the original.
                var adapters = baseCaps.Adapters.GetEnumerator();
                while (adapters.MoveNext())
                {
                    caps.Adapters.Add(adapters.Key, adapters.Value);
                }

                // Copy the browsers from the original to prevent the Browsers
                // property returning null.
                if (baseCaps.Browsers != null)
                {
                    foreach (string browser in baseCaps.Browsers)
                    {
                        caps.AddBrowser(browser);
                    }
                }
            }
            else
            {
                // No 51Degrees active provider is present so we have to use
                // the base capabilities only.
                caps = baseCaps;
            }
            return(caps);
        }
コード例 #11
0
        /// <summary>
        /// A reference to the active provider.
        /// </summary>
        internal static WebProvider GetActiveProvider()
        {
            if (_activeProviderCreated == false)
            {
                lock (_lock)
                {
                    if (_activeProviderCreated == false)
                    {
                        _activeProvider = Create();

                        // The DetectorModule should set to listen for the
                        // application reycling or shutting down. This is belt
                        // and braces in case thte HttpModule method fails to
                        // fire the application end event.
                        AppDomain.CurrentDomain.ProcessExit += OnProcessExit;

                        _activeProviderCreated = true;
                    }
                }
            }
            return _activeProvider;
        }
コード例 #12
0
 /// <summary>
 /// Forces the application to reload the active provider on the next
 /// request.
 /// </summary>
 public static void Refresh()
 {
     var provider = _activeProvider;
     _activeProvider = null;
     _activeProviderCreated = false;
     if (provider != null)
     {
         // Dispose of the old provider.
         provider.Dispose();
     }
 }
コード例 #13
0
 /// <summary>
 /// Writes information about the data set being used by the provider.
 /// </summary>
 /// <param name="writer"></param>
 /// <param name="provider"></param>
 private static void WriteProvider(XmlWriter writer, WebProvider provider)
 {
     if (provider != null)
     {
         writer.WriteStartElement("DataSet");
         writer.WriteElementString("Version", provider.DataSet.Version.ToString());
         writer.WriteElementString("Name", provider.DataSet.Name);
         writer.WriteEndElement();
     }
 }
コード例 #14
0
        private static LicenceKeyResults ActivateDownloadedFile(WebClient client, string uncompressedTempFile)
        {
            var status = LicenceKeyResults.Success;

            // Rename the current master file to a temp file so enable the new
            // master file to take it's place and to rollback if there's a problem.
            var tempCopyofCurrentMaster = String.Format("{0}.tmp", BinaryFile.FullName);

            try
            {
                // Both the MD5 hash was good and the provider was created.
                // Save the data and force the factory to reload.

                if (BinaryFile.Exists)
                {
                    // Keep a copy of the old data in case we need to go back to it.
                    File.Move(BinaryFile.FullName, tempCopyofCurrentMaster);
                }

                // Copy the new file to the master file.
                File.Move(uncompressedTempFile, BinaryFile.FullName);

                // Get the published date from the new data file.
                var publishedDate = WebProvider.GetDataFileDate(BinaryFile.FullName);

                // Sets the last modified time of the file downloaded to the one
                // provided in the HTTP header, or if not valid then the published
                // date of the data set.
                DateTime lastModified;
                if (DateTime.TryParseExact(
                        client.ResponseHeaders[HttpResponseHeader.LastModified],
                        "R",
                        CultureInfo.InvariantCulture,
                        DateTimeStyles.AssumeUniversal,
                        out lastModified) == false)
                {
                    lastModified = publishedDate.Value;
                }
                BinaryFile.LastWriteTimeUtc = lastModified.ToUniversalTime();

                EventLog.Info(String.Format(
                                  "Automatically updated binary data file '{0}' with version " +
                                  "published on the '{1:d}'.",
                                  BinaryFile.FullName,
                                  publishedDate));
            }
            catch (Exception ex)
            {
                if (BinaryFile.Exists == false)
                {
                    File.Move(tempCopyofCurrentMaster, BinaryFile.FullName);
                }
                EventLog.Warn(ex);
                status = LicenceKeyResults.WriteDataFile;
            }
            finally
            {
                File.Delete(tempCopyofCurrentMaster);
            }

            return(status);
        }
コード例 #15
0
        /// <summary>
        /// Forces the provider to update current ActiveProvider with new data.
        /// </summary>
        private static WebProvider Create()
        {
            WebProvider provider = null;
            CleanTemporaryFiles();
            try
            {
                // Does a binary file exist?
                if (Manager.BinaryFilePath != null)
                {
                    // Log API version for diagnosis.
                    var assembly = Assembly.GetExecutingAssembly().GetName();
                    EventLog.Info(String.Format(
                        "Creating data set from '{0}' version '{1}'",
                        assembly.Name,
                        assembly.Version));

                    if (File.Exists(Manager.BinaryFilePath))
                    {
                        if (Manager.MemoryMode)
                        {
                            EventLog.Info(String.Format(
                                "Creating memory byte array dataset and provider from binary data file '{0}'.",
                                Manager.BinaryFilePath));
                            provider = new WebProvider(StreamFactory.Create(File.ReadAllBytes(Manager.BinaryFilePath)));
                        }
                        else
                        {
                            provider = new WebProvider(GetTempFileDataSet());
                        }
                        EventLog.Info(String.Format(
                            "Created provider from version '{0}' format '{1}' data published on '{2:u}' in master file '{3}'.",
                            provider.DataSet.Version,
                            provider.DataSet.Name,
                            provider.DataSet.Published,
                            Manager.BinaryFilePath));
                    }
                    else
                    {
                        EventLog.Info("Data file at '{0}' could not be found. Either it does not exist or " +
                            "there is insufficient permission to read it. Check the AppPool has read permissions " +
                            "and the application is not running in medium trust if the data file is not in the " +
                            "application directory.", Manager.BinaryFilePath);
                    }
                }
            }
            catch (Exception ex)
            {
                // Record the exception in the log file.
                EventLog.Fatal(
                    new MobileException(String.Format(
                        "Exception processing device data from binary file '{0}'. " +
                        "Enable debug level logging and try again to help identify cause.",
                        Manager.BinaryFilePath),
                        ex));
            }

            // Does the provider exist and has data been loaded?
            if (provider == null || provider.DataSet == null)
            {
                EventLog.Fatal("No data source available to create provider.");
            }

            return provider;
        }
コード例 #16
0
 /// <summary>
 /// The application is being disposed of either due to a recycle event or 
 /// shutdown. Ensure the active provider is disposed of to release resources.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private static void OnProcessExit(object sender, EventArgs e)
 {
     try
     {
         var provider = _activeProvider;
         if (provider != null)
         {
             provider.Dispose();
         }
     }
     finally
     {
         _activeProvider = null;
         _activeProviderCreated = false;
     }
 }
コード例 #17
0
        /// <summary>
        /// Forces the provider to update current ActiveProvider with new data.
        /// </summary>
        private static WebProvider Create()
        {
            WebProvider provider = null;

            CleanTemporaryFiles();
            try
            {
                // Does a binary file exist?
                if (Manager.BinaryFilePath != null)
                {
                    // Log API version for diagnosis.
                    var assembly = Assembly.GetExecutingAssembly().GetName();
                    EventLog.Info(String.Format(
                                      "Creating data set from '{0}' version '{1}'",
                                      assembly.Name,
                                      assembly.Version));

                    if (File.Exists(Manager.BinaryFilePath))
                    {
                        if (Manager.MemoryMode)
                        {
                            EventLog.Info(String.Format(
                                              "Creating memory byte array dataset and provider from binary data file '{0}'.",
                                              Manager.BinaryFilePath));
                            provider = new WebProvider(StreamFactory.Create(File.ReadAllBytes(Manager.BinaryFilePath)));
                        }
                        else
                        {
                            provider = new WebProvider(GetTempFileDataSet());
                        }
                        EventLog.Info(String.Format(
                                          "Created provider from version '{0}' format '{1}' data published on '{2:u}' in master file '{3}'.",
                                          provider.DataSet.Version,
                                          provider.DataSet.Name,
                                          provider.DataSet.Published,
                                          Manager.BinaryFilePath));
                    }
                    else
                    {
                        EventLog.Info("Data file at '{0}' could not be found. Either it does not exist or " +
                                      "there is insufficient permission to read it. Check the AppPool has read permissions " +
                                      "and the application is not running in medium trust if the data file is not in the " +
                                      "application directory.", Manager.BinaryFilePath);
                    }
                }
            }
            catch (Exception ex)
            {
                // Record the exception in the log file.
                EventLog.Fatal(
                    new MobileException(String.Format(
                                            "Exception processing device data from binary file '{0}'. " +
                                            "Enable debug level logging and try again to help identify cause.",
                                            Manager.BinaryFilePath),
                                        ex));
            }

            // Does the provider exist and has data been loaded?
            if (provider == null || provider.DataSet == null)
            {
                EventLog.Fatal("No data source available to create provider.");
            }

            return(provider);
        }