/// <summary> /// Create an Unmanaged Database Proxy. /// </summary> /// <param name="database"> /// An <see cref="IUnmanagedBrowsingDatabase" /> to proxy to. /// </param> /// <param name="ownDatabase"> /// A boolean flag indicating whether or not the unmanaged database proxy takes ownership of /// <paramref name="database" /> and disposes it when the unmanaged database proxy itself is disposed. If /// the unmanaged database proxy takes ownership of <paramref name="database" /> and you reference or /// dispose <paramref name="database" /> after you create the unmanaged database proxy, the behavior of the /// unmanaged database proxy and <paramref name="database" /> is undefined. /// </param> /// <returns> /// An unmanaged database proxy. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="database" /> is a null reference. /// </exception> internal static UnmanagedBrowsingDatabaseProxy Create(IUnmanagedBrowsingDatabase database, bool ownDatabase) { // ... // // Throws an exception if the operation fails. return(database is UnmanagedBrowsingDatabaseProxy databaseProxy ? databaseProxy : new UnmanagedBrowsingDatabaseProxy(database, ownDatabase)); }
/// <summary> /// Compute a Threat List's Checksum Asynchronously. /// </summary> /// <param name="this"> /// An <see cref="IUnmanagedBrowsingDatabase" />. /// </param> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> whose checksum should /// be computed. /// </param> /// <param name="cancellationToken"> /// A cancellation token to cancel the asynchronous operation with. /// </param> /// <returns> /// The checksum, formatted as a hexadecimal encoded string, of the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="this" /> is a null reference, or if <paramref name="threatListDescriptor" /> /// is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if <paramref name="this" /> is disposed. /// </exception> /// <exception cref="System.OperationCanceledException"> /// Thrown if the asynchronous operation is cancelled. /// </exception> public static async Task <string> ComputeThreatListChecksumAsync(this IUnmanagedBrowsingDatabase @this, ThreatListDescriptor threatListDescriptor, CancellationToken cancellationToken) { Guard.ThrowIf(nameof(@this), @this).Null(); // ... // // Throws an exception if the operation fails. var getThreatsTask = @this.GetThreatsAsync(threatListDescriptor, cancellationToken); var threats = await getThreatsTask.ConfigureAwait(false); try { string threatListChecksum = null; if (threats.Count != 0) { // ... // // Throws an exception if the decoding, hashing, or encoding operations fail. They will typically // fail if the database is corrupt in anyway. threatListChecksum = threats.OrderBy(t => t) .Join() .HexadecimalDecode() .Sha256Hash() .HexadecimalEncode(); } return(threatListChecksum); } catch (Exception ex) { const string detailMessage = "A threat list's checksum could not be computed."; throw new BrowsingDatabaseException(detailMessage, ex); } }
/// <summary> /// Create a Resilient Unmanaged Database. /// </summary> /// <param name="database"> /// An <see cref="IUnmanagedBrowsingDatabase" /> to proxy to. /// </param> /// <param name="retryAttempts"> /// The number of attempts a failed operation should be retried. /// </param> /// <param name="ownDatabase"> /// A boolean flag indicating whether or not the resilient unmanaged database takes ownership of /// <paramref name="database" /> and disposes it when the resilient unmanaged database itself is disposed. /// If the resilient unmanaged database takes ownership of <paramref name="database" /> and you reference /// or dispose <paramref name="database" /> after you create the resilient unmanaged database, the behavior /// of the resilient unmanaged database and <paramref name="database" /> is undefined. /// </param> /// <returns> /// A resilient unmanaged database. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="database" /> is a null reference. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// Thrown if <paramref name="retryAttempts" /> is less than or equal to <c>0</c>. /// </exception> public static ResilientUnmanagedBrowsingDatabase Create(IUnmanagedBrowsingDatabase database, int retryAttempts, bool ownDatabase) { // ... // // Throws an exception if the operation fails. return(database is ResilientUnmanagedBrowsingDatabase resilientDatabase ? resilientDatabase : new ResilientUnmanagedBrowsingDatabase(database, retryAttempts, ownDatabase)); }
/// <summary> /// Compute a Threat List's Checksum Asynchronously. /// </summary> /// <param name="this"> /// An <see cref="IUnmanagedBrowsingDatabase" />. /// </param> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> whose checksum should /// be computed. /// </param> /// <returns> /// The checksum, formatted as a hexadecimal encoded string, of the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="this" /> is a null reference, or if <paramref name="threatListDescriptor" /> /// is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if <paramref name="this" /> is disposed. /// </exception> public static Task <string> ComputeThreatListChecksumAsync(this IUnmanagedBrowsingDatabase @this, ThreatListDescriptor threatListDescriptor) { // ... // // Throws an exception if the operation fails. return(@this.ComputeThreatListChecksumAsync(threatListDescriptor, CancellationToken.None)); }
/// <summary> /// Create a Resilient Unmanaged Database. /// </summary> /// <param name="database"> /// An <see cref="IUnmanagedBrowsingDatabase" /> to proxy to. /// </param> /// <param name="retryAttempts"> /// The number of attempts a failed operation should be retried. /// </param> /// <param name="ownDatabase"> /// A boolean flag indicating whether or not the resilient unmanaged database takes ownership of /// <paramref name="database" /> and disposes it when the resilient unmanaged database itself is disposed. /// If the resilient unmanaged database takes ownership of <paramref name="database" /> and you reference /// or dispose <paramref name="database" /> after you create the resilient unmanaged database, the behavior /// of the resilient unmanaged database and <paramref name="database" /> is undefined. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="database" /> is a null reference. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// Thrown if <paramref name="retryAttempts" /> is less than or equal to <c>0</c>. /// </exception> public ResilientUnmanagedBrowsingDatabase(IUnmanagedBrowsingDatabase database, int retryAttempts, bool ownDatabase) : base(retryAttempts) { Guard.ThrowIf(nameof(retryAttempts), retryAttempts).LessThanOrEqualTo(0); this._database = UnmanagedBrowsingDatabaseProxy.Create(database, ownDatabase); this._disposed = false; this._ownDatabase = ownDatabase; }
/// <summary> /// Create an Unmanaged Database Proxy. /// </summary> /// <param name="database"> /// An <see cref="IUnmanagedBrowsingDatabase" /> to proxy to. /// </param> /// <param name="ownDatabase"> /// A boolean flag indicating whether or not the unmanaged database proxy takes ownership of /// <paramref name="database" /> and disposes it when the unmanaged database proxy itself is disposed. If /// the unmanaged database proxy takes ownership of <paramref name="database" /> and you reference or /// dispose <paramref name="database" /> after you create the unmanaged database proxy, the behavior of the /// unmanaged database proxy and <paramref name="database" /> is undefined. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="database" /> is a null reference. /// </exception> private UnmanagedBrowsingDatabaseProxy(IUnmanagedBrowsingDatabase database, bool ownDatabase) { Guard.ThrowIf(nameof(database), database).Null(); this._database = database; this._disposed = false; this._ownDatabase = ownDatabase; }
/// <summary> /// Set Database. /// </summary> /// <param name="value"> /// A <see cref="IManagedBrowsingDatabase" /> to store the collection of retrieved /// <see cref="ThreatList" /> in. /// </param> /// <param name="ownDatabase"> /// A boolean flag indicating whether or not the <see cref="UnmanagedBrowsingService" /> takes ownership of /// the database and disposes it when the unmanaged service itself is disposed. If the unmanaged service /// takes ownership of the database and you reference or dispose the database after you create the /// unmanaged service, the behavior of the unmanaged service and the database is undefined. /// </param> /// <returns> /// This unmanaged service builder. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="value" /> is a null reference. /// </exception> public UnmanagedBrowsingServiceBuilder SetDatabase(IUnmanagedBrowsingDatabase value, bool ownDatabase) { Guard.ThrowIf(nameof(value), value).Null(); this.Database = value; this.OwnDatabase = ownDatabase; return(this); }
/// <summary> /// Find Threat Lists Asynchronously. /// </summary> /// <param name="this"> /// An <see cref="IUnmanagedBrowsingDatabase" />. /// </param> /// <param name="threatSha256HashPrefix"> /// A SHA256 hash prefix, formatted as a hexadecimal encoded string, identifying a threat associated with /// the collection of <see cref="ThreatList" /> to retrieve. /// </param> /// <returns> /// A collection of <see cref="ThreatList" /> the threat identified by /// <paramref name="threatSha256HashPrefix" /> is associated with. An empty collection indicates no threat /// lists were found. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="this" /> is a null reference, or if /// <paramref name="threatSha256HashPrefix" /> is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if <paramref name="this" /> is disposed. /// </exception> public static Task <IReadOnlyCollection <ThreatList> > FindThreatListsAsync(this IUnmanagedBrowsingDatabase @this, string threatSha256HashPrefix) { Guard.ThrowIf(nameof(@this), @this).Null(); // ... // // Throws an exception if the operation fails. var findThreatListsTask = @this.FindThreatListsAsync(threatSha256HashPrefix, CancellationToken.None); return(findThreatListsTask); }
/// <summary> /// Get Threats Asynchronously. /// </summary> /// <param name="this"> /// An <see cref="IUnmanagedBrowsingDatabase" />. /// </param> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> the threats that should /// be retrieved are associated with. /// </param> /// <returns> /// A collection of SHA256 hash prefixes, formatted as hexadecimal encoded strings, identifying the threats /// that are associated with the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. An empty collection indicates no threats were found. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="this" /> is a null reference, or if <paramref name="threatListDescriptor" /> /// is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if <paramref name="this" /> is disposed. /// </exception> public static Task <IReadOnlyCollection <string> > GetThreatsAsync(this IUnmanagedBrowsingDatabase @this, ThreatListDescriptor threatListDescriptor) { Guard.ThrowIf(nameof(@this), @this).Null(); // ... // // Throws an exception if the operation fails. var getThreatsTask = @this.GetThreatsAsync(threatListDescriptor, CancellationToken.None); return(getThreatsTask); }
private UnmanagedBrowsingDatabaseProxy(IUnmanagedBrowsingDatabase database) : this(database, true) { }
/// <summary> /// Lookup a URL. /// </summary> /// <param name="cache"> /// A <see cref="IBrowsingCache" />. /// </param> /// <param name="client"> /// A <see cref="IBrowsingClient" />. /// </param> /// <param name="database"> /// An <see cref="IUnmanagedBrowsingDatabase" />. /// </param> /// <param name="url"> /// A <see cref="Url" /> to lookup. /// </param> /// <param name="cancellationToken"> /// A cancellation token to cancel the asynchronous operation with. /// </param> /// <returns> /// A <see cref="UrlLookupResult" /> indicating whether <paramref name="url" /> is /// <see cref="UrlLookupResultCode.Safe" /> or <see cref="UrlLookupResultCode.Unsafe" />. /// </returns> /// <exception cref="Gee.External.Browsing.Cache.BrowsingCacheException"> /// Thrown if a caching error occurs. If you're not interested in handling this exception, catch /// <see cref="BrowsingException" /> instead. /// </exception> /// <exception cref="Gee.External.Browsing.Clients.BrowsingClientException"> /// Thrown if an error communicating with the Google Safe Browsing API occurs. If you're not interested /// in handling this exception, catch <see cref="BrowsingException" /> instead. /// </exception> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. If you're not interested in handling this exception, catch /// <see cref="BrowsingException" /> instead. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="url" /> is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if <paramref name="cache" /> is disposed, or if <paramref name="client" /> is disposed, or if /// <paramref name="database" /> is disposed. /// </exception> /// <exception cref="System.OperationCanceledException"> /// Thrown if the asynchronous operation is cancelled. /// </exception> private protected async Task <UrlLookupResult> LookupAsync(IBrowsingCache cache, IBrowsingClient client, IUnmanagedBrowsingDatabase database, Url url, CancellationToken cancellationToken) { // ... // // First, lookup the URL in the local database. Throws an exception if the operation fails. var urlLookupDate = DateTime.UtcNow; UrlLookupResult urlLookupResult; var databaseLookupTask = database.LookupAsync(url); var databaseLookResult = await databaseLookupTask.ConfigureAwait(false); if (databaseLookResult.IsDatabaseMiss) { // ... // // If the URL does not exist in the local database, indicate the URL is safe. urlLookupResult = UrlLookupResult.Safe(url, urlLookupDate); } else if (databaseLookResult.IsDatabaseStale) { // ... // // If the local database is expired/out-of-date/stale, indicate the nature of the URL cannot // be determined as a result. urlLookupResult = UrlLookupResult.DatabaseStale(url, urlLookupDate); } else { // ... // // If the URL exists in the local database, look it up in the cache. Throws an exception if // the operation fails. var sha256Hash = databaseLookResult.Sha256Hash; var sha256HashPrefix = databaseLookResult.Sha256HashPrefix; var cacheLookupTask = cache.LookupAsync(sha256Hash, sha256HashPrefix, cancellationToken); var cacheLookupResult = await cacheLookupTask.ConfigureAwait(false); if (cacheLookupResult.IsCacheSafeHit) { // ... // // If we get a cache safe hit, indicate the URL is safe. urlLookupResult = UrlLookupResult.Safe(url, urlLookupDate); } else if (cacheLookupResult.IsCacheUnsafeHit) { // ... // // If we get a cache unsafe hit, indicate the URL is unsafe. If we get a cache unsafe hit, // it is guaranteed we find a URL expression for the threat, since it is essentially the // URL expression that is cached. var unsafeThreatListDescriptors = cacheLookupResult.UnsafeThreatListDescriptors; url.TryGetExpressionForSha256Hash(sha256Hash, out var unsafeUrlExpression); urlLookupResult = UrlLookupResult.Unsafe(url, urlLookupDate, unsafeUrlExpression, unsafeThreatListDescriptors); } else { // ... // // If we get a cache miss, verify the URL with the Google Safe Browsing API. Throws an // exception if the operation fails. var threatLists = databaseLookResult.ThreatLists; var findFullHashesTask = client.FindFullHashesAsync(sha256HashPrefix, threatLists, cancellationToken); var fullHashResponse = await findFullHashesTask.ConfigureAwait(false); // ... // // Throws an exception if the operation fails. var safeCacheEntryExpirationDate = fullHashResponse.SafeThreatsExpirationDate; var putSafeCacheEntryTask = cache.PutSafeCacheEntryAsync(sha256HashPrefix, safeCacheEntryExpirationDate, cancellationToken); await putSafeCacheEntryTask.ConfigureAwait(false); var unsafeThreats = fullHashResponse.UnsafeThreats; if (unsafeThreats.Count != 0) { var unsafeThreatGroups = unsafeThreats.GroupBy(ut => ut.Sha256Hash); foreach (var unsafeThreatGroup in unsafeThreatGroups) { // ... // // Throws an exception if the operation fails. var unsafeThreatSha256Hash = unsafeThreatGroup.Key; var putUnsafeCacheEntryTask = cache.PutUnsafeCacheEntryAsync(unsafeThreatSha256Hash, unsafeThreatGroup, cancellationToken); await putUnsafeCacheEntryTask.ConfigureAwait(false); } } // ... // // Lookup the URL in the cache again. Throws an exception if the operation fails. cacheLookupTask = cache.LookupAsync(sha256Hash, sha256HashPrefix, cancellationToken); cacheLookupResult = await cacheLookupTask.ConfigureAwait(false); if (cacheLookupResult.IsCacheSafeHit) { // ... // // If we get a cache safe hit, indicate the URL is safe. urlLookupResult = UrlLookupResult.Safe(url, urlLookupDate); } else if (cacheLookupResult.IsCacheUnsafeHit) { // ... // // If we get a cache unsafe hit, indicate the URL is unsafe. If we get a cache unsafe hit, // it is guaranteed we find a URL expression for the threat, since it is essentially the // URL expression that is cached. var unsafeThreatListDescriptors = cacheLookupResult.UnsafeThreatListDescriptors; url.TryGetExpressionForSha256Hash(sha256Hash, out var unsafeUrlExpression); urlLookupResult = UrlLookupResult.Unsafe(url, urlLookupDate, unsafeUrlExpression, unsafeThreatListDescriptors); } else { urlLookupResult = UrlLookupResult.DatabaseStale(url, urlLookupDate); } } } return(urlLookupResult); }
/// <summary> /// Create an Unmanaged Database Proxy. /// </summary> /// <param name="database"> /// An <see cref="IUnmanagedBrowsingDatabase" /> to proxy to. The unmanaged database proxy takes ownership /// of <paramref name="database" /> and will dispose it when the unmanaged database proxy itself is /// disposed. If you reference or dispose <paramref name="database" /> after you create the unmanaged /// database proxy, the behavior of the unmanaged database proxy and <paramref name="database" /> is /// undefined. /// </param> /// <returns> /// An unmanaged database proxy. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="database" /> is a null reference. /// </exception> internal static UnmanagedBrowsingDatabaseProxy Create(IUnmanagedBrowsingDatabase database) => UnmanagedBrowsingDatabaseProxy.Create(database, true);
/// <summary> /// Create a Resilient Unmanaged Database. /// </summary> /// <param name="database"> /// An <see cref="IUnmanagedBrowsingDatabase" /> to proxy to. The resilient unmanaged database takes /// ownership of <paramref name="database" /> and will dispose it when the resilient unmanaged database /// itself is disposed. If you reference or dispose <paramref name="database" /> after you create the /// resilient unmanaged database, the behavior of the resilient unmanaged database and /// <paramref name="database" /> is undefined. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="database" /> is a null reference. /// </exception> public ResilientUnmanagedBrowsingDatabase(IUnmanagedBrowsingDatabase database) : this(database, 5, true) { }
/// <summary> /// Create a Resilient Unmanaged Database. /// </summary> /// <param name="database"> /// An <see cref="IUnmanagedBrowsingDatabase" /> to proxy to. The resilient unmanaged database takes /// ownership of <paramref name="database" /> and will dispose it when the resilient unmanaged database /// itself is disposed. If you reference or dispose <paramref name="database" /> after you create the /// resilient unmanaged database, the behavior of the resilient unmanaged database and /// <paramref name="database" /> is undefined. /// </param> /// <param name="retryAttempts"> /// The number of attempts a failed operation should be retried. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="database" /> is a null reference. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// Thrown if <paramref name="retryAttempts" /> is less than or equal to <c>0</c>. /// </exception> public ResilientUnmanagedBrowsingDatabase(IUnmanagedBrowsingDatabase database, int retryAttempts) : this(database, retryAttempts, true) { }
/// <summary> /// Create a Resilient Unmanaged Database. /// </summary> /// <param name="database"> /// An <see cref="IUnmanagedBrowsingDatabase" /> to proxy to. The resilient unmanaged database takes /// ownership of <paramref name="database" /> and will dispose it when the resilient unmanaged database /// itself is disposed. If you reference or dispose <paramref name="database" /> after you create the /// resilient unmanaged database, the behavior of the resilient unmanaged database and /// <paramref name="database" /> is undefined. /// </param> /// <returns> /// A resilient unmanaged database. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="database" /> is a null reference. /// </exception> public static ResilientUnmanagedBrowsingDatabase Create(IUnmanagedBrowsingDatabase database) => ResilientUnmanagedBrowsingDatabase.Create(database, 5);
public static async Task <IReadOnlyCollection <ThreatList> > GetThreatListsAsync(this IUnmanagedBrowsingDatabase @this, IEnumerable <ThreatListDescriptor> threatListDescriptors) { Guard.ThrowIf(nameof(@this), @this).Null(); Guard.ThrowIf(nameof(threatListDescriptors), threatListDescriptors).Null(); var threatLists = new List <ThreatList>(); foreach (var threatListDescriptor in threatListDescriptors) { // ... // // Throws an exception if the operation fails. var getThreatListTask = @this.GetThreatListAsync(threatListDescriptor); var threatList = await getThreatListTask.ConfigureAwait(false); threatList = threatList ?? ThreatList.CreateInvalid(threatListDescriptor); threatLists.Add(threatList); } return(threatLists); }
/// <summary> /// Lookup a URL Asynchronously. /// </summary> /// <param name="this"> /// A database. /// </param> /// <param name="url"> /// A URL to lookup. /// </param> /// <returns> /// A database lookup result indicating the nature of lookup operation. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="this" /> is a null reference, or if <paramref name="url" /> is a null /// reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if <paramref name="this" /> is disposed. /// </exception> public static Task <DatabaseLookupResult> LookupAsync(this IUnmanagedBrowsingDatabase @this, Url url) { Guard.ThrowIf(nameof(@this), @this).Null(); Guard.ThrowIf(nameof(url), url).Null(); var lookupTask = LookupAsync(@this, url); return(lookupTask); // <summary> // Lookup a URL Asynchronously. // </summary> async Task <DatabaseLookupResult> LookupAsync(IUnmanagedBrowsingDatabase cThis, Url cUrl) { DatabaseLookupResult cDatabaseLookupResult = null; foreach (var cUrlExpression in cUrl.Expressions) { foreach (var cSha256HashPrefix in cUrlExpression.Sha256HashPrefixes) { // ... // // Throws an exception if the operation fails. var cFindThreatListsTask = cThis.FindThreatListsAsync(cSha256HashPrefix); var cThreatLists = await cFindThreatListsTask.ConfigureAwait(false); if (cThreatLists.Count != 0) { var cSha256Hash = cUrlExpression.Sha256Hash; cDatabaseLookupResult = DatabaseLookupResult.DatabaseHit(cSha256Hash, cSha256HashPrefix, cThreatLists); break; } } if (cDatabaseLookupResult != null) { break; } } if (cDatabaseLookupResult == null) { // ... // // Throws an exception if the operation fails. var cGetThreatListsTask = cThis.GetThreatListsAsync(); var cThreatLists = await cGetThreatListsTask.ConfigureAwait(false); if (cThreatLists.Count == 0) { cDatabaseLookupResult = DatabaseLookupResult.DatabaseStale(); } else { foreach (var cThreatList in cThreatLists) { if (cThreatList.Expired) { cDatabaseLookupResult = DatabaseLookupResult.DatabaseStale(); break; } } } } cDatabaseLookupResult = cDatabaseLookupResult ?? DatabaseLookupResult.DatabaseMiss(); return(cDatabaseLookupResult); } }
/// <summary> /// Create a Resilient Unmanaged Database. /// </summary> /// <param name="database"> /// An <see cref="IUnmanagedBrowsingDatabase" /> to proxy to. The resilient unmanaged database takes /// ownership of <paramref name="database" /> and will dispose it when the resilient unmanaged database /// itself is disposed. If you reference or dispose <paramref name="database" /> after you create the /// resilient unmanaged database, the behavior of the resilient unmanaged database and /// <paramref name="database" /> is undefined. /// </param> /// <param name="retryAttempts"> /// The number of attempts a failed operation should be retried. /// </param> /// <returns> /// A resilient unmanaged database. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="database" /> is a null reference. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// Thrown if <paramref name="retryAttempts" /> is less than or equal to <c>0</c>. /// </exception> public static ResilientUnmanagedBrowsingDatabase Create(IUnmanagedBrowsingDatabase database, int retryAttempts) => ResilientUnmanagedBrowsingDatabase.Create(database, retryAttempts, true);