/// <summary> /// Find Full Hashes Asynchronously. /// </summary> /// <param name="this"> /// A <see cref="IBrowsingClient" />. /// </param> /// <param name="request"> /// A <see cref="FullHashRequest" />. /// </param> /// <returns> /// A <see cref="FullHashResponse" />. /// </returns> /// <exception cref="Gee.External.Browsing.Clients.BrowsingClientException"> /// Thrown if an error communicating with the Google Safe Browsing API occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="this" /> is a null reference, or if <paramref name="request" /> is a null /// reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if <paramref name="this" /> is disposed. /// </exception> /// <exception cref="System.TimeoutException"> /// Thrown if communication with the Google Safe Browsing API times out. /// </exception> public static Task <FullHashResponse> FindFullHashesAsync(this IBrowsingClient @this, FullHashRequest request) { Guard.ThrowIf(nameof(@this), @this).Null(); // ... // // Throws an exception if the operation fails. var findFullHashesTask = @this.FindFullHashesAsync(request, CancellationToken.None); return(findFullHashesTask); }
public static Task <FullHashResponse> FindFullHashesAsync(this IBrowsingClient @this, string sha256HashPrefix, IEnumerable <ThreatList> threatLists, CancellationToken cancellationToken) { Guard.ThrowIf(nameof(@this), @this).Null(); Guard.ThrowIf(nameof(threatLists), threatLists).Null(); // ... // // Throws an exception if the operation fails. var fullHashRequestBuilder = FullHashRequest.Build(); fullHashRequestBuilder.AddSha256HashPrefix(sha256HashPrefix); foreach (var threatList in threatLists) { fullHashRequestBuilder.AddQuery(threatList.Descriptor, threatList.State); } // ... // // Throws an exception if the operation fails. var fullHashRequest = fullHashRequestBuilder.Build(); var findFullHashesTask = @this.FindFullHashesAsync(fullHashRequest, cancellationToken); return(findFullHashesTask); }
/// <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> /// Find Full Hashes Asynchronously. /// </summary> /// <param name="this"> /// A <see cref="IBrowsingClient" />. /// </param> /// <param name="sha256HashPrefix"> /// A SHA256 hash prefix, formatted as a hexadecimal encoded string, identifying a threat to query. /// </param> /// <param name="threatLists"> /// A collection of <see cref="ThreatList" /> the threat identified by <paramref name="sha256HashPrefix" /> /// is associated with. /// </param> /// <returns> /// A <see cref="FullHashResponse" />. /// </returns> /// <exception cref="Gee.External.Browsing.Clients.BrowsingClientException"> /// Thrown if an error communicating with the Google Safe Browsing API occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="this" /> is a null reference, or if <paramref name="sha256HashPrefix" /> is a /// null reference, or if <paramref name="threatLists" /> is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if the <paramref name="this" /> is disposed. /// </exception> /// <exception cref="System.TimeoutException"> /// Thrown if communication with the Google Safe Browsing API times out. /// </exception> public static Task <FullHashResponse> FindFullHashesAsync(this IBrowsingClient @this, string sha256HashPrefix, IEnumerable <ThreatList> threatLists) => @this.FindFullHashesAsync(sha256HashPrefix, threatLists, CancellationToken.None);